#include "xtal.h"
#include "xtal_bind.h"
#include "xtal_macro.h"
#include "xtal_details.h"
#include "xtal_stringspace.h"
#include "xtal_parser.h"

namespace xtal{

namespace{

void Iterator_each(const VMachinePtr& vm){
	vm->return_result(vm->arg_this());
}

void Iterator_block_first(const VMachinePtr& vm){
	vm->arg_this()->rawsend(vm, Xid2(block_next));
}

void VMachine_current_context(const VMachinePtr& vm){
	vm->return_result(vm->current_context2());
}

const AnyPtr& Any_p(const AnyPtr& v){
	stdout_stream()->println(v);
	return v;
}

StringPtr Any_to_s(const AnyPtr& v){
	return Xf1("<%s>", 0, v->object_name());
}

bool Any_op_in_Array(const AnyPtr& v, const ArrayPtr& values){
	const VMachinePtr& vm = vmachine();
	Xfor(n, values){
		if(XTAL_detail_raweq(n, v)){
			return true;
		}

		vm->setup_call(1);
		vm->push_arg(v);
		n->rawsend(vm, Xid2(op_eq));
		if(vm->is_executed() && vm->result()){
			vm->cleanup_call();
			return true;
		}
		vm->cleanup_call();
	}

	return false;
}

bool Any_op_in_Set(const AnyPtr& v, const MapPtr& values){
	return !!values->at(v);
}

void Any_this(const VMachinePtr& vm){
	vm->return_result(vm->arg_this());
}

void Stream_put_s(const StreamPtr& stream, const StringPtr& str){
	stream->put_s(str);
}

StringPtr String_format(const StringPtr& str){
	return format(str);
}

TextPtr String_text(const StringPtr& str){
	return text(str);
}

const AnyPtr& Array_op_at(const ArrayPtr& a, int_t n){
	return a->op_at(n);
}

void Array_op_set_at(const ArrayPtr& a, int_t n, const AnyPtr& v){
	return a->op_set_at(n, v);
}

void builtin_print(const AnyPtr& str){
	stdout_stream()->print(str);
}

void builtin_println(const AnyPtr& str){
	stdout_stream()->println(str);
}

void builtin_printf(const StringPtr& format_string, const ArgumentsPtr& args){
	stdout_stream()->printf(format_string, args);
}

AnyPtr builtin_load(const StringPtr& file_name, const ArgumentsPtr& args){
	if(CodePtr code = compile_file(file_name)){
		return code->call(args);
	}
	return undefined;
}

#ifndef XTAL_NO_PARSER

void eval(const VMachinePtr& vm){
	AnyPtr ev = vm->arg(0);
	int_t depth = vm->arg_default(1, 0)->to_i();

	if(CodePtr code = ptr_cast<Code>(ev)){
		vm->return_result(vm->eval(code, depth+1));
		return;
	}

	vm->return_result(vm->eval(eval_compile(ev), depth+1));
}

#endif

}

XTAL_PREBIND(ChRangeIter){
	Xregister(Builtin);
	Xinherit(Iterator);
}

XTAL_BIND(ChRangeIter){
	Xdef_method(block_next);
}

XTAL_PREBIND(ChRange){
	Xregister(Builtin);
	Xinherit(Range);
	Xdef_ctor2(const StringPtr&, const StringPtr&);
}

XTAL_BIND(ChRange){
	Xdef_method(each);
}

XTAL_PREBIND(Values){
	Xregister(Builtin);
	Xfinal();
	Xinherit(Iterator);
}

XTAL_BIND(Values){
	Xdef_method(block_next);
	Xdef_method(op_at);
	Xdef_method(size);
	Xdef_method(op_eq);
	Xdef_method(to_s);
}

XTAL_PREBIND(String){
	Xregister(Builtin);
	Xfinal();
	Xinherit(Iterable);
}

XTAL_BIND(String){
	Xdef_method_alias(op_call, &String::on_rawcall);

	Xdef_method(to_i);
	Xdef_method(to_f);
	Xdef_method(to_s);
	Xdef_method(clone);
	Xdef_method(length);
	Xdef_method(data_size);
	Xdef_method(intern);
	Xdef_method(is_interned);	// バインド漏れ修正 by 星くず彼方に
	Xdef_method(is_ch);
	Xdef_method(ascii);
	Xdef_method(cat);			// バインド漏れ修正 by 星くず彼方に

	Xdef_method2(op_range, String);
	Xdef_method2(op_cat, String);
	Xdef_method_alias2(op_cat_assign, &Self::op_cat, String);
	Xdef_method2(op_eq, String);
	Xdef_method2(op_lt, String);
	Xdef_method2(op_in, ChRange);
	
	Xdef_method_alias(p, &Any_p);
}

XTAL_PREBIND(Any){
	Xregister(Builtin);
}

XTAL_BIND(Any){
	Xdef_method_alias(class, &Any::get_class);
	Xdef_method(get_class);
	Xdef_method(object_name);
	Xdef_method(object_name_list);
	Xdef_method_alias(p, &Any_p);
	Xdef_method_alias(to_s, &Any_to_s);
	Xdef_method_alias2(op_in, &Any_op_in_Array, Array);
	Xdef_method_alias2(op_in, &Any_op_in_Set, Set);
	Xdef_method2(op_eq, Any);
}

XTAL_BIND2(Any){
	for(int i=DefinedID::id_op_call; i<=DefinedID::id_op_in; ++i){
		it->def_double_dispatch_method(fetch_defined_id(i));
	}
}

XTAL_PREBIND(Undefined){
	Xregister(Builtin);
	Xfinal();
}

XTAL_PREBIND(Bool){
	Xregister(Builtin);
	Xinherit(Iterator);
	Xfinal();
}

XTAL_PREBIND(Null){
	Xregister(Builtin);
	Xinherit(Iterator);
	Xfinal();
}

XTAL_PREBIND(ImmediateValue){
	Xregister(Builtin);
	Xfinal();
}

XTAL_PREBIND(Int){
	Xregister(Builtin);
	Xinherit(Float);
	Xfinal();
}

XTAL_BIND(Int){
	Xdef_method(to_i);
	Xdef_method(to_f);
	Xdef_method_alias(f, &Int::to_f);
	Xdef_method_alias(F, &Int::to_f);
	Xdef_method(to_s);
	Xdef_method_alias2(op_range, &Int::op_range_Int, Int);
	Xdef_method_alias2(op_range, &Int::op_range_Float, Float);
	Xdef_method_alias2(op_in, &Int::op_in_IntRange, IntRange);
	Xdef_method_alias2(op_in, &Int::op_in_FloatRange, FloatRange);
}

XTAL_PREBIND(Float){
	Xregister(Builtin);
	Xfinal();
}

XTAL_BIND(Float){
	Xdef_method(to_i);
	Xdef_method(to_f);
	Xdef_method_alias(f, &Float::to_f);
	Xdef_method_alias(F, &Float::to_f);
	Xdef_method(to_s);
	Xdef_method_alias2(op_range, &Float::op_range_Int, Int);
	Xdef_method_alias2(op_range, &Float::op_range_Float, Float);
	Xdef_method_alias2(op_in, &Float::op_in_IntRange, IntRange);
	Xdef_method_alias2(op_in, &Float::op_in_FloatRange, FloatRange);
}

XTAL_PREBIND(IntRangeIter){
	Xinherit(Iterator);
}

XTAL_BIND(IntRangeIter){
	Xdef_method(block_next);
}

XTAL_PREBIND(Range){
	Xregister(Builtin);
	Xinherit(Iterable);

	Xdef_ctor3(const AnyPtr&, const AnyPtr&, int_t);
		Xparam(kind, 0);
}

XTAL_BIND(Range){
	Xdef_method(left);
	Xdef_method(right);
	Xdef_method(kind);

	Xdef_const(CLOSED);
	Xdef_const(LEFT_OPEN_RIGHT_CLOSED);
	Xdef_const(LEFT_CLOSED_RIGHT_OPEN);
	Xdef_const(OPEN);
}

XTAL_PREBIND(IntRange){
	Xregister(Builtin);
	Xinherit(Range);
	Xdef_ctor3(int_t, int_t, int_t);
		Xparam(kind, 0);
}

XTAL_BIND(IntRange){
	Xdef_method(begin);
	Xdef_method(end);
	Xdef_method(each);
}

XTAL_PREBIND(FloatRange){
	Xregister(Builtin);
	Xinherit(Range);
	Xdef_ctor3(float_t, float_t, int_t);
		Xparam(kind, 0);
}

XTAL_BIND(FloatRange){
}

XTAL_PREBIND(ArrayIter){
	Xinherit(Iterator);
}

XTAL_BIND(ArrayIter){
	Xdef_method(block_next);
}

XTAL_PREBIND(Array){
	Xregister(Builtin);
	Xfinal();
	Xinherit(Iterable);

	Xdef_ctor1(int_t);
		Xparam(size, 0);
}

XTAL_BIND(Array){

	Xdef_method(size);
	Xdef_method(length);
	Xdef_method(resize);
	Xdef_method(upsize);	// バインド漏れ修正 by 星くず彼方に
	Xdef_method(downsize);	// バインド漏れ修正 by 星くず彼方に

	Xdef_method(empty);
	Xdef_method(is_empty);
	
	Xdef_method(slice);
		Xparam(n, 1);
	
	Xdef_method(splice);
		Xparam(n, 1);
	
	Xdef_method(pop_back);
	Xdef_method(pop_front);
	Xdef_method(push_back);
	Xdef_method(push_front);

	Xdef_method(erase);
		Xparam(n, 1);

	Xdef_method(insert);
	Xdef_method(each);
	Xdef_method(clone);
	Xdef_method(front);
	Xdef_method(back);
	Xdef_method(clear);
	Xdef_method(reverse);
	Xdef_method(assign);
	Xdef_method(append);

	Xdef_method(op_to_array);
	Xdef_method2(op_cat, Array);
	Xdef_method2(op_cat_assign, Array);
	Xdef_method2(op_eq, Array);
	
	Xdef_method_alias2(op_at, &Array_op_at, Int);
	Xdef_method_alias2(op_set_at, &Array_op_set_at, Int);
	Xdef_method_alias2(op_call, &Array_op_at, Int);

	Xdef_method(join);
		Xparam(sep, empty_string);

	Xdef_method(to_s);
	Xdef_method(block_first);

}

XTAL_PREBIND(MapIter){
	Xinherit(Iterator);
}

XTAL_BIND(MapIter){
	Xdef_method(block_next);
}

XTAL_PREBIND(Map){
	Xregister(Builtin);
	Xinherit(Iterable);
	Xdef_ctor0();
}

XTAL_BIND(Map){
	Xdef_method(size);
	Xdef_method(length);
	Xdef_method(insert);
	Xdef_method(each);
	Xdef_method(pairs);
	Xdef_method(keys);
	Xdef_method(values);
	Xdef_method(clone);
	Xdef_method(clear);
	Xdef_method(erase);
	Xdef_method(empty);
	Xdef_method(is_empty);
	Xdef_method(assign);
	Xdef_method(append);
	Xdef_method(default_value);		// バインド漏れ修正 by 星くず彼方に
	Xdef_method(set_default_value);	// バインド漏れ修正 by 星くず彼方に

	Xdef_method(op_to_map);
	Xdef_method2(op_at, Any);
	Xdef_method2(op_set_at, Any);
	Xdef_method2(op_cat, Map);
	Xdef_method2(op_cat_assign, Map);
	Xdef_method_alias2(op_call, &Map::op_at, Any);

	Xdef_method(block_first);
	Xdef_method(to_s);
}

XTAL_PREBIND(Set){
	Xregister(Builtin);
	Xinherit(Map);
	Xdef_ctor0();
}

XTAL_BIND(Set){
	Xdef_method(each);
	Xdef_method(to_s);
}

XTAL_PREBIND(Fun){
	Xregister(Builtin);
	Xinherit(Method);
}

XTAL_PREBIND(Fiber){
	Xregister(Builtin);
	Xinherit(Fun);
	Xinherit(Iterator);
}

XTAL_BIND(Fiber){
	Xdef_method(reset);
	Xdef_method_alias(block_first, &Fiber::block_next);
	Xdef_method(block_next);
	Xdef_method_alias(block_break, &Fiber::halt);
	Xdef_method(halt);
	Xdef_method(is_alive);
	Xdef_method_alias(to_fiber, &Any_this);
}

XTAL_PREBIND(Lambda){
	Xregister(Builtin);
	Xinherit(Fun);
}

XTAL_PREBIND(Arguments){
	Xregister(Builtin);
	Xinherit(Iterable);
	Xdef_ctor2(const AnyPtr&, const AnyPtr&);
		Xparam(ordered, null);
		Xparam(named, null);
}

XTAL_BIND(Arguments){
	Xdef_method_alias(size, &Arguments::length);
	Xdef_method(length);
	Xdef_method(ordered_arguments);
	Xdef_method(named_arguments);
	
	Xdef_method_alias2(op_at, &Arguments::op_at_int, Int);
	Xdef_method_alias2(op_at, &Arguments::op_at_string, String);

	Xdef_double_dispatch_method(op_at);

	Xdef_method(each);
	Xdef_method_alias(pairs, &Arguments::each);
	Xdef_method(to_s);
}

XTAL_PREBIND(ArgumentsIter){
	Xinherit(Iterator);
}

XTAL_BIND(ArgumentsIter){
	Xdef_method(block_next);
}

XTAL_PREBIND(Code){
	Xregister(Builtin);
	Xinherit(Class);
}

XTAL_BIND(Code){
	Xdef_method(filelocal);
	Xdef_method(inspect);
}

XTAL_PREBIND(MembersIter){
	Xinherit(Iterator);
}

XTAL_BIND(MembersIter){
	Xdef_method(block_next);
}

XTAL_PREBIND(MembersIter2){
	Xinherit(Iterator);
}

XTAL_BIND(MembersIter2){
	Xdef_method(block_next);
}

XTAL_PREBIND(InheritedClassesIter){
	Xinherit(Iterator);
}

XTAL_BIND(InheritedClassesIter){
	Xdef_method(block_next);
}


XTAL_BIND(Frame){
	Xdef_method(members);
	Xdef_method(outer);
}

XTAL_PREBIND(Class){
	Xregister(Builtin);
	Xinherit(Frame);
}

XTAL_BIND(Class){
	Xdef_method_alias(inherit, &Class::inherit_strict);
	Xdef_method(overwrite);
	Xdef_method(s_new);
	Xdef_method(inherited_classes);
	Xdef_method(is_inherited);

	Xdef_method(find_near_member);
		Xparam(secondary_key, undefined);
}

XTAL_PREBIND(ZipIter){
	Xregister_alias(Builtin, zip);
	Xinherit(Iterator);
	Xdef_ctor1(const VMachinePtr&);
}

XTAL_BIND(ZipIter){
	Xdef_method(block_first);
	Xdef_method(block_next);
	Xdef_method(block_break);
}

#ifndef XTAL_NO_THREAD

XTAL_PREBIND(Thread){
	Xregister(Builtin);
	Xdef_ctor0();
}

XTAL_BIND(Thread){
	Xdef_method(start);
	Xdef_method(join);
	Xdef_fun_alias(yield, &yield_thread);
	Xdef_fun_alias(sleep, &sleep_thread);
}

XTAL_PREBIND(Mutex){
	Xregister(Builtin);
	Xdef_ctor0();
}

XTAL_BIND(Mutex){
	Xdef_method(lock);
	Xdef_method(unlock);
}

#endif

XTAL_PREBIND(Text){
	Xregister(Builtin);
	Xdef_serial_ctor();
}

XTAL_BIND(Text){
	Xdef_method(to_s);
	Xdef_method(serial_save);
	Xdef_method(serial_load);
}

XTAL_PREBIND(NativeMethod){
	Xregister(Builtin);	
}

XTAL_PREBIND(NativeFun){
	Xregister(Builtin);
	Xinherit(NativeMethod);
}

XTAL_PREBIND(Stream){
	Xregister(Builtin);
}

XTAL_BIND(Stream){
	Xdef_method(get_s);
	Xdef_method(get_s_all);
	
	Xdef_method_alias(put_s, &Stream_put_s);

	Xdef_method(print);
	Xdef_method(println);
	Xdef_method(printf);

	Xdef_method(seek);
	Xdef_method(tell);
	Xdef_method(pour);
	Xdef_method(pour_all);
	Xdef_method(size);
	Xdef_method(close);

	Xdef_method(flush);

	Xdef_method(eos);

	Xdef_method(serialize);
	Xdef_method(deserialize);

	Xdef_method(block_first);
	Xdef_method(block_next);
	Xdef_method(block_break);

	Xdef_method(put_i8);
	Xdef_method(put_u8);

	Xdef_method(put_i16be);
	Xdef_method(put_i32be);
	Xdef_method(put_u16be);
	Xdef_method(put_u32be);
	Xdef_method(put_f32be);

	Xdef_method(put_i16le);
	Xdef_method(put_i32le);
	Xdef_method(put_u16le);
	Xdef_method(put_u32le);
	Xdef_method(put_f32le);

	Xdef_method(get_u8);
	Xdef_method(get_i8);

	Xdef_method(get_i16be);
	Xdef_method(get_i32be);
	Xdef_method(get_u16be);
	Xdef_method(get_u32be);
	Xdef_method(get_f32be);

	Xdef_method(get_i16le);
	Xdef_method(get_i32le);
	Xdef_method(get_u16le);
	Xdef_method(get_u32le);
	Xdef_method(get_f32le);
}

XTAL_PREBIND(PointerStream){
	Xinherit(Stream);
}

XTAL_PREBIND(MemoryStream){
	Xregister(Builtin);
	Xinherit(PointerStream);
	Xdef_ctor0();
}

XTAL_BIND(MemoryStream){
	Xdef_method(to_s);
	Xdef_method(resize);
}

XTAL_PREBIND(StringStream){
	Xregister(Builtin);
	Xinherit(Stream);
	Xdef_ctor1(const StringPtr&);
}

XTAL_BIND(StringStream){
	Xdef_method(to_s);
}

XTAL_PREBIND(FileStream){
	Xregister(Builtin);
	Xinherit(Stream);
	Xdef_ctor2(const StringPtr&, const StringPtr&);
}

XTAL_PREBIND(CompressEncoder){
	Xregister(Builtin);
	Xinherit(Stream);
	Xdef_ctor1(const StreamPtr&);
}

XTAL_PREBIND(CompressDecoder){
	Xregister(Builtin);
	Xinherit(Stream);
	Xdef_ctor1(const StreamPtr&);
}

XTAL_PREBIND(StdinStream){
	Xregister(Builtin);
	Xinherit(Stream);
}

XTAL_PREBIND(StdoutStream){
	Xregister(Builtin);
	Xinherit(Stream);
}

XTAL_PREBIND(StderrStream){
	Xregister(Builtin);
	Xinherit(Stream);
}

namespace debug{

XTAL_PREBIND(HookInfo){
	Xregister(Debug);
}

XTAL_BIND(HookInfo){
	Xdef_method(clone);
	Xdef_method(kind);
	Xdef_method(fun);
	Xdef_method(lineno);
	Xdef_method(fun_name);
	Xdef_method(file_name);
	Xdef_method(exception);
	Xdef_method(variables_frame);

	//Xdef_method(set_kind);
	//Xdef_method(set_line);
	//Xdef_method(set_fun_name);
	//Xdef_method(set_file_name);
	//Xdef_method(set_exception);
	//Xdef_method(set_variables_frame);

	Xdef(LINE, (int_t)BREAKPOINT_LINE);
	Xdef(CALL, (int_t)BREAKPOINT_CALL);
	Xdef(RETURN, (int_t)BREAKPOINT_RETURN);
	Xdef(THROW, (int_t)BREAKPOINT_THROW);
}

XTAL_PREBIND(Debug){
	Xregister_alias(Builtin, debug);
}

XTAL_BIND(Debug){
	Xdef_fun_alias(enable, &enable);
	Xdef_fun_alias(disable, &disable);
	Xdef_fun_alias(enable_force, &enable_force);	// バインド漏れ修正 by 星くず彼方に
	Xdef_fun_alias(disable_force, &disable_force);	// バインド漏れ修正 by 星くず彼方に
	Xdef_fun_alias(is_enabled, &is_enabled);

	Xdef_fun_alias(breakpoint_hook, &breakpoint_hook);
	Xdef_fun_alias(call_hook, &call_hook);
	Xdef_fun_alias(return_hook, &return_hook);
	Xdef_fun_alias(throw_hook, &throw_hook);
	Xdef_fun_alias(assert_hook, &assert_hook);	// バインド漏れ修正 by 星くず彼方に

	Xdef_fun_alias(set_breakpoint_hook, &set_breakpoint_hook);
	Xdef_fun_alias(set_call_hook, &set_call_hook);
	Xdef_fun_alias(set_return_hook, &set_return_hook);
	Xdef_fun_alias(set_throw_hook, &set_throw_hook);
	Xdef_fun_alias(set_assert_hook, &set_assert_hook);	// バインド漏れ修正 by 星くず彼方に
}

}

XTAL_PREBIND(Iterable){
	Xregister(Builtin);
	Xxtal_class();
}

XTAL_BIND(Iterable){
	// Iterableがバインドされるなら、Iteratorもバインドしてしまう
	// なぜなら、IterableはIteratorにメンバ取得を委譲するから
	cpp_class<Iterator>()->bind();
}

XTAL_PREBIND(Iterator){
	Xregister(Builtin);
	Xinherit(Iterable);
	Xxtal_class();
}

XTAL_BIND(Iterator){
	Xdef_fun_alias(each, &Iterator_each);
	Xdef_fun_alias(block_first, &Iterator_block_first);
}

XTAL_PREBIND(Exception){
	Xregister(Builtin);
	Xdef_ctor1(const StringPtr&);
		Xparam(message, empty_string);
}

XTAL_BIND(Exception){
	Xdef_method(initialize);
		Xparam(message, empty_string);
	
	Xdef_method(to_s);
	Xdef_method(message);
	Xdef_method(backtrace);
	Xdef_method(append_backtrace);
}

XTAL_PREBIND(StandardError){
	Xregister(Builtin);
	Xxtal_class();
	Xinherit(Exception);
}

XTAL_PREBIND(RuntimeError){
	Xregister(Builtin);
	Xxtal_class();
	Xinherit(StandardError);
}

XTAL_PREBIND(IOError){
	Xregister(Builtin);
	Xxtal_class();
	Xinherit(StandardError);
}

XTAL_PREBIND(EOSError){
	Xregister(Builtin);
	Xxtal_class();
	Xinherit(StandardError);
}

XTAL_PREBIND(LogicError){
	Xregister(Builtin);
	Xxtal_class();
	Xinherit(StandardError);
}

XTAL_PREBIND(CastError){
	Xregister(Builtin);
	Xxtal_class();
	Xinherit(StandardError);
}

XTAL_PREBIND(ArgumentError){
	Xregister(Builtin);
	Xxtal_class();
	Xinherit(StandardError);
}

XTAL_PREBIND(YieldError){
	Xregister(Builtin);
	Xxtal_class();
	Xinherit(StandardError);
}

XTAL_PREBIND(InstanceVariableError){
	Xregister(Builtin);
	Xxtal_class();
	Xinherit(StandardError);
}

XTAL_PREBIND(UnsupportedError){
	Xregister(Builtin);
	Xxtal_class();
	Xinherit(StandardError);
}

XTAL_PREBIND(RedefinedError){
	Xregister(Builtin);
	Xxtal_class();
	Xinherit(StandardError);
}

XTAL_PREBIND(AccessibilityError){
	Xregister(Builtin);
	Xxtal_class();
	Xinherit(StandardError);
}

XTAL_PREBIND(AssertionFailed){
	Xregister(Builtin);
	Xxtal_class();
	Xinherit(Exception);
}

XTAL_PREBIND(CompileError){
	Xregister(Builtin);
	Xxtal_class();
	Xinherit(StandardError);
}

namespace filesystem{

XTAL_PREBIND(Filesystem){
	Xregister_alias(Builtin, filesystem);
}

XTAL_BIND(Filesystem){
	Xdef_fun_alias(open, &open);
	Xdef_fun_alias(entries, &entries);
	Xdef_fun_alias(is_directory, &is_directory);
}

XTAL_PREBIND(Entries){
	Xregister(Filesystem);
	Xinherit(Iterator);
}

XTAL_BIND(Entries){
	Xdef_method(block_next);
	Xdef_method(block_break);
}

}

namespace{

AnyPtr abs(const AnyPtr& a){
	switch(XTAL_detail_type(a)){XTAL_DEFAULT;
		XTAL_CASE(TYPE_INT){ return XTAL_detail_ivalue(a)<0 ? AnyPtr(-XTAL_detail_ivalue(a)) : a; }
		XTAL_CASE(TYPE_FLOAT){ return XTAL_detail_fvalue(a)<0 ? AnyPtr(-XTAL_detail_fvalue(a)) : a; }
	}
	return 0;
}

struct f2{
	float_t a, b;
};

inline void to_f2(f2& ret, int_t atype, const AnyPtr& a, int_t btype, const AnyPtr& b){
	float_t aa[2] = {(float_t)XTAL_detail_ivalue(a), XTAL_detail_fvalue(a)};
	float_t bb[2] = {(float_t)XTAL_detail_ivalue(b), XTAL_detail_fvalue(b)};
	ret.a = aa[atype];
	ret.b = bb[btype];
}

AnyPtr max_(const AnyPtr& a, const AnyPtr& b){
	uint_t btype = XTAL_detail_type(b)-TYPE_INT;
	uint_t atype = XTAL_detail_type(a)-TYPE_INT;
	uint_t abtype = atype | btype;

	if(abtype==0){
		return XTAL_detail_ivalue(a) < XTAL_detail_ivalue(b) ? b : a;	
	}

	if(abtype==1){
		f2 ab;
		to_f2(ab, atype, a, btype, b);
		return ab.a < ab.b ? b : a;	
	}

	return null;
}

AnyPtr min_(const AnyPtr& a, const AnyPtr& b){
	uint_t btype = XTAL_detail_type(b)-TYPE_INT;
	uint_t atype = XTAL_detail_type(a)-TYPE_INT;
	uint_t abtype = atype | btype;

	if(abtype==0){
		return XTAL_detail_ivalue(a) < XTAL_detail_ivalue(b) ? a : b;	
	}

	if(abtype==1){
		f2 ab;
		to_f2(ab, atype, a, btype, b);
		return ab.a < ab.b ? a : b;	
	}

	return null;
}

class Random{
public:

	Random(int_t seed=1){ 
		set_seed(seed); 
	}
	
	void set_seed(int_t seed){
		idum_ = seed==0 ? 1 : seed; 
	} 

	float_t operator ()();
	
	float_t operator ()(float_t max){
		return (*this)()*max; 
	}

	float_t operator ()(float_t min, float_t max){
		return (*this)()*(max-min)+min; 
	}	

private:
	enum{ IA=16807,IM=2147483647,IQ=127773,IR=2836 };
	int_t idum_;
};

float_t Random::operator ()(){
	int_t idum = idum_;
	int_t k = idum/IQ;
	idum = IA*(idum-k*IQ)-IR*k;
	idum &= IM;
	idum_ = idum;
	return ((float_t)1.0/IM)*idum;
}	

Random random_instance;

float_t random(){
	return random_instance();
}

float_t random_range(float_t in, float_t ax){
	return random_instance(in, ax);
}

}

template<class T>
struct TMath;

template<>
struct TMath<float>{
	static float acos(float v){ using namespace std; return acosf(v); }
	static float asin(float v){ using namespace std; return asinf(v); }
	static float atan(float v){ using namespace std; return atanf(v); }
	static float atan2(float v, float u){ using namespace std; return atan2f(v, u); }
	static float ceil(float v){ using namespace std; return ceilf(v); }
	static float cos(float v){ using namespace std; return cosf(v); }
	static float exp(float v){ using namespace std; return expf(v); }
	static float floor(float v){ using namespace std; return floorf(v); }
	static float log(float v){ using namespace std; return logf(v); }
	static float pow(float v, float u){ using namespace std; return powf(v, u); }
	static float sin(float v){ using namespace std; return sinf(v); }
	static float sqrt(float v){ using namespace std; return sqrtf(v); }
	static float tan(float v){ using namespace std; return tanf(v); }
};

template<>
struct TMath<double>{
	static double acos(double v){ using namespace std; return acos(v); }
	static double asin(double v){ using namespace std; return asin(v); }
	static double atan(double v){ using namespace std; return atan(v); }
	static double atan2(double v, double u){ using namespace std; return atan2(v, u); }
	static double ceil(double v){ using namespace std; return ceil(v); }
	static double cos(double v){ using namespace std; return cos(v); }
	static double exp(double v){ using namespace std; return exp(v); }
	static double floor(double v){ using namespace std; return floor(v); }
	static double log(double v){ using namespace std; return log(v); }
	static double pow(double v, double u){ using namespace std; return pow(v, u); }
	static double sin(double v){ using namespace std; return sin(v); }
	static double sqrt(double v){ using namespace std; return sqrt(v); }
	static double tan(double v){ using namespace std; return tan(v); }
};

struct Math : TMath<float_t>{};

XTAL_PREBIND(Math){
	Xregister_alias(Builtin, math);
}

XTAL_BIND(Math){
	Xdef_fun(acos);
	Xdef_fun(asin);
	Xdef_fun(atan);
	Xdef_fun(atan2);
	Xdef_fun(ceil);
	Xdef_fun(cos);
	Xdef_fun(exp);
	Xdef_fun(floor);
	Xdef_fun(log);
	Xdef_fun(pow);
	Xdef_fun(sin);
	Xdef_fun(sqrt);
	Xdef_fun(tan);

	Xdef_fun_alias(abs, &abs);
	Xdef_fun_alias(max, &max_);
	Xdef_fun_alias(min, &min_);
	Xdef_fun_alias(random, &random);
	Xdef_fun_alias(random_range, &random_range);

	Xdef(PI, (float_t)3.14159265358979);
	Xdef(E, (float_t)2.71828182845905);
}

XTAL_PREBIND(TreeNode){
	Xregister(Builtin);
	Xfinal();
	Xinherit(Array);
}

XTAL_BIND(TreeNode){
	Xdef_method(tag);
	Xdef_method(lineno);
	Xdef_method(set_tag);
	Xdef_method(set_lineno);
	Xdef_method(op_at);
	Xdef_method(op_set_at);
}

namespace xpeg{

class Xpeg{};
class XpegOperator{};

XTAL_PREBIND(Xpeg){
	Xregister_alias(Builtin, xpeg);
	Xxtal_class();
}

XTAL_BIND(Xpeg){
	Xdef_fun_alias(elem, &elem);
}

XTAL_PREBIND(XpegOperator){
	Xregister(Xpeg);
	Xxtal_class();
}

XTAL_PREBIND(Element){
	Xregister(Xpeg);
	Xdef_ctor4(int_t, const AnyPtr&, const AnyPtr&, int_t);
		Xparam(param1, null);
		Xparam(param2, null);
		Xparam(param3, 0);
}

XTAL_BIND(Element){
	Xdef_var(type);
	Xdef_var(param1);
	Xdef_var(param2);
	Xdef_var(param3);

	Xdef_method(op_com);

	Xdef_const(TYPE_INVALID);
	Xdef_const(TYPE_ANY);
	Xdef_const(TYPE_BOS);
	Xdef_const(TYPE_EOS);
	Xdef_const(TYPE_BOL);
	Xdef_const(TYPE_EOL);
	Xdef_const(TYPE_BACKREF);
	Xdef_const(TYPE_EQL);
	Xdef_const(TYPE_PRED);
	Xdef_const(TYPE_CALL);
	Xdef_const(TYPE_INT_RANGE);
	Xdef_const(TYPE_FLOAT_RANGE);
	Xdef_const(TYPE_CH_RANGE);
	Xdef_const(TYPE_CH_SET);
	Xdef_const(TYPE_GREED);
	Xdef_const(TYPE_LOOKAHEAD);
	Xdef_const(TYPE_LOOKBEHIND);
	Xdef_const(TYPE_LEAF);
	Xdef_const(TYPE_NODE);
	Xdef_const(TYPE_ERROR);
	Xdef_const(TYPE_CONCAT);
	Xdef_const(TYPE_OR);
	Xdef_const(TYPE_MORE0);
	Xdef_const(TYPE_MORE1);
	Xdef_const(TYPE_01);
	Xdef_const(TYPE_EMPTY);
	Xdef_const(TYPE_CAP);
	Xdef_const(TYPE_DECL);
}

XTAL_PREBIND(Executor){
	Xregister(Xpeg);

	Xdef_ctor1(const StringPtr&);
		Xparam(source, empty_string);
}

XTAL_BIND(Executor){
	//Xdef_method(reset);
	Xdef_method(parse);
	Xdef_method(match);

	Xdef_method(captures);
	Xdef_method(captures_values);		
	Xdef_method_alias2(op_at, &Executor::at, String);
	Xdef_method_alias2(op_call, &Executor::call, String);
	Xdef_method(prefix);
	Xdef_method(suffix);
	Xdef_method(prefix_values);
	Xdef_method(suffix_values);
	Xdef_method(errors);
	Xdef_method(read);

	Xdef_method(peek);
		Xparam(n, 0);

	Xdef_method(tree);
	Xdef_method(bos);
	Xdef_method(eos);
}

XTAL_PREBIND(StreamExecutor){
	Xinherit(Executor);
	Xregister(Xpeg);

	Xdef_ctor2(const StreamPtr&, const StringPtr&);
		Xparam(source_name, empty_string);
}

XTAL_PREBIND(IteratorExecutor){
	Xinherit(Executor);
	Xregister(Xpeg);

	Xdef_ctor2(const AnyPtr&, const StringPtr&);
		Xparam(source_name, empty_string);
}

}

//*

XTAL_PREBIND(AutoLoader){
	Xinherit(Class);
	Xregister(Builtin);
	Xdef_ctor0();
}

XTAL_BIND(AutoLoader){
	Xdef_method(append_load_path);
}

XTAL_PREBIND(Builtin){
	Xinherit(Global);
	Xregister_alias(Lib, builtin);
	Xregister_alias(Builtin, builtin);
	Xxtal_class();
	Xsingleton();
}

XTAL_BIND(Builtin){
	Xdef_fun_alias(assign_text_map, &assign_text_map);
	Xdef_fun_alias(append_text_map, &append_text_map);
	Xdef_fun_alias(format, &String_format);
	Xdef_fun_alias(text, &String_text);
	Xdef_fun_alias(current_context, &VMachine_current_context);
	
	Xdef_fun_alias(require, &require);
	Xdef_fun_alias(require_source, &require_source);

	Xdef_fun_alias(gc, &::xtal::gc);
	Xdef_fun_alias(full_gc, &::xtal::full_gc);
	Xdef_fun_alias(disable_gc, &::xtal::disable_gc);
	Xdef_fun_alias(enable_gc, &::xtal::enable_gc);
	Xdef_fun_alias(set_gc_stress, &::xtal::set_gc_stress);
	//Xdef_fun_alias(clock, &clock_);

	Xdef_fun_alias(print, &builtin_print);
	Xdef_fun_alias(println, &builtin_println);
	Xdef_fun_alias(printf, &builtin_printf);

	Xdef_fun_alias(open, &xtal::open);
		Xparam(mode, XTAL_STRING("r"));
	
	Xdef_fun_alias(load, &builtin_load);
	Xdef_fun_alias(compile_file, &compile_file);
	Xdef_fun_alias(compile, &compile);
		Xparam(source_name, XTAL_STRING(""));

#ifndef XTAL_NO_PARSER
	Xdef_fun_alias(eval_compile, &eval_compile);
	Xdef_fun_alias(eval, &eval);
#endif
}

void bind(){
	using namespace xpeg;
	static CppClassSymbolData* classes[4] = {&CppClassSymbol<Element>::value, &CppClassSymbol<ChRange>::value, &CppClassSymbol<String>::value, &CppClassSymbol<Fun>::value };
	for(int i=0; i<4; ++i){
		cpp_class(classes[i])->inherit(cpp_class<XpegOperator>());
	}		
}

//*/

////////////////////////////////////////////////////////////////////////
//*

XTAL_BIND2(Bool){
	Xemb((
Bool::block_next: method{ return null, this; }
Bool::block_first: Bool::block_next;
Bool::to_s: method this ? "true" : "false";

),
"\xdf\x78\x74\x61\x6c\x02\xe8\xf3\x37\x00\xff\x30\x00\x02\x01\x4b\x00\x01\x00\xff\x0a\x00\x01\x3c\x00\x01\x06\x00\xf7\x3c\x00\x02"
"\x0a\x00\x00\x00\x4a\x00\xd5\x03\xeb\xf0\x01\xfa\xf1\x02\xfb\xf1\x32\xcd\xfd\x02\x14\x00\x4a\x00\x04\x00\x00\xcd\xfc\x19\x02\xfe"
"\xf0\x02\x00\x11\x00\x06\x00\x75\x1d\x14\x00\x07\x0c\x00\x01\x00\x1b\x2a\x00\xbd\x02\x0c\x02\x01\x00\x3c\xcd\x11\x01\x05\x08\x2c"
"\x04\x09\x00\x2e\x00\x51\x2a\x01\xe9\xf2\xf2\xf4\x6c\x0a\x08\xf2\xf1\x15\x01\xea\xf1\x1d\xeb\xf0\x59\x00\x16\x02\x6b\x0f\x10\x88"
"\x03\x89\x05\x9b\x02\x9b\x03\x05\x59\x00\x89\x02\x9b\x05\x82\xeb\xf0\x20\x59\x00\x95\x02\xd1\x06\xd1\x08\x98\x04\x36\xf6\x00\x00"
"\x01\x0b\xeb\xf0\x11\x74\x6f\x6f\xff\x6c\x2f\x74\x65\x6d\x70\x2f\x69\x3b\x6e\x2e\xee\xf1\x00\x07\x0e\xea\xf1\x1d\x11\xff\x08\x74"
"\x6f\x70\x6c\x65\x76\x65\xcd\x6c\x1d\x11\x04\x42\x0b\x10\x1d\x11\x0a\x62\xff\x6c\x6f\x63\x6b\x5f\x6e\x65\x78\xf5\x74\x1d\x11\x0b"
"\x3d\x13\x66\x69\x72\x73\xbe\x46\x12\x04\x74\x6f\x5f\x73\x1d\x11\x09\xcf\x66\x69\x6c\x65\x3e\x10\x19\x10\x03\x03\xbe\x05\x11\x04"
"\x74\x72\x75\x65\x05\x11\x05\x3f\x66\x61\x6c\x73\x65\x03"
);
}

XTAL_BIND2(Null){

	Xemb((
Null::each: method null;
Null::op_to_array: method [];
Null::op_to_map: method [:];
Null::block_first: method null;
),
"\xdf\x78\x74\x61\x6c\x02\xe8\xf3\x3f\x00\xff\x30\x00\x02\x01\x4b\x00\x01\x00\x7f\x09\x00\x01\x3c\x00\x00\x3c\x00\x00\xfe\x06\x00"
"\x00\x4a\x00\x03\x00\x00\x91\xfd\x01\xfa\xf4\x02\x00\x08\x00\x42\x00\x7b\x3c\x97\x0b\x05\x04\x00\x00\xcd\x17\x05\xdd\x03\x20\x00"
"\x44\x00\x3c\x32\x00\x3c\xcd\x8a\x0f\x01\x05\x30\x08\x04\x02\x01\x46\x00\x41\x07\x06\x0a\x30\x04\x07\x40\x02\x51\x68\x01\xe9\xf2"
"\xf2\xf4\x7c\x0a\x88\xf2\xf1\x13\x00\xe9\xf2\x11\xeb\xf0\x2f\x00\xe9\xf2\x1f\x48\xeb\xf0\x4b\x00\xe9\xf2\x2d\xeb\xf0\x79\x03\x01"
"\x7a\x0f\x10\xaf\x04\x99\x05\xc3\x02\xc3\x03\x05\x4b\x00\x99\x02\xc3\x05\x22\xeb\xf0\x14\x4b\x00\xa5\x02\xf9\x08\x22\x4b\x00\xb1"
"\x02\x82\xf9\x08\x30\x4b\x00\x79\x02\xf9\x06\xf9\x08\xc0\x04\x3e\xf6\x00\x00\x01\x0b\x9e\x01\x74\x6f\x6f\x6c\xff\x2f\x74\x65\x6d"
"\x70\x2f\x69\x6e\x9d\x2e\xee\xf1\x00\x08\x0e\xea\xf1\x6d\x11\x08\xff\x74\x6f\x70\x6c\x65\x76\x65\x6c\xde\x6d\x11\x04\x4e\x75\x6c"
"\x7e\x13\x65\x61\xfb\x63\x68\x6d\x11\x0b\x6f\x70\x5f\x74\x7f\x6f\x5f\x61\x72\x72\x61\x79\x6d\x11\xdd\x09\x96\x13\x6d\x61\x70\x91"
"\x12\x62\x6c\xff\x6f\x63\x6b\x5f\x66\x69\x72\x73\x3d\x74\xa1\x12\x66\x69\x6c\x65\xb5\x10\x69\x10\x07\x01\x03\x03"
);

}

XTAL_BIND2(String){

	Xemb((

String::each: method StringStream(this).chars;

String::scan: method(pattern){
	return StringStream(this).scan(pattern);
}

String::split: method(pattern){
	return StringStream(this).split(pattern);
}

String::match: method(pattern){
	return StringStream(this).match(pattern);
}

String::parse: method(pattern){
	return StringStream(this).parse(pattern);
}

String::gsub: method(pattern, fn){
	mm: MemoryStream();
	exec: xpeg::StreamExecutor(StringStream(this));
	if(exec.match(pattern)){
		prefix: exec.prefix;
		mm.put_s(prefix);
		mm.put_s(fn(exec));

		while(exec.match(pattern)){
			prefix: exec.prefix;
			mm.put_s(prefix);
			mm.put_s(fn(exec));
		}

		mm.put_s(exec.suffix);
		return mm.to_s;
	}
	else{
		return this;
	}
}

String::sub: method(pattern, fn){
	mm: MemoryStream();
	exec: xpeg::StreamExecutor(StringStream(this));
	if(exec.match(pattern)){
		prefix: exec.prefix;
		suffix: exec.suffix;
		mm.put_s(prefix);
		mm.put_s(fn(exec));
		mm.put_s(exec.suffix);
		return mm.to_s;
	}
	else{
		return this;
	}
}

),
"\xdf\x78\x74\x61\x6c\x02\xe9\xf2\x01\x3c\xff\x00\x30\x00\x02\x01\x4b\x00\x01\xff\x00\x10\x02\x30\x00\x03\x03\x06\xff\x01\x34\x02"
"\x01\x01\x03\x00\x38\x7f\x00\x04\x02\x01\x00\x3c\xcd\x15\x01\x7f\x00\x00\x4a\x00\x05\x00\x00\x18\x00\xee\xfb\xf3\x02\x00\x14\x04"
"\x09\x02\x07\xcd\xff\xff\x00\x36\x01\x01\x00\x08\x02\x94\x23\x01\x17\x07\x08\x22\x08\x03\x2e\x0f\x40\x02\x0b\x4a\x46\x0c\x0b\x22"
"\x08\x04\x62\x0f\x40\x02\x0e\x46\x0c\xa5\x0e\x22\x08\x05\x96\x0f\x40\x02\x11\x46\x0c\x11\xee\x22\x08\x06\x00\x68\xfa\xf0\x16\xfc"
"\x34\xfe\x00\x00\x01\x01\x30\x00\x17\x00\x32\xca\x18\x00\x18\x04\x09\xfd\x05\x10\x23\x10\x07\xcd\xaf\xfa\x00\x36\xfd\xab\x00\x01"
"\x23\x01\x1d\xfe\x60\x00\x46\xfe\x38\x00\x19\x00\xfd\xff\x00\x07\xcd\xfe\x00\x39\x00\x1a\x7b\x00\xfc\x26\x10\xfd\x00\x34\xfb\x23"
"\x10\x2c\x44\x16\x29\x1d\x1f\xff\x3b\x15\xff\x44\x1f\x56\x1f\xef\x00\x1d\xff\xe9\x20\x00\x1b\xff\xe6\xce\x10\x00\x1b\x01\xfd\x78"
"\x13\x10\x00\x1c\x01\x55\xfc\x16\x02\x1b\x20\x00\x06\x16\x08\x1d\x22\x08\x87\x07\x00\x45\x00\x11\x20\x11\x08\x1f\x0a\x03\xfe\x5e"
"\x21\x15\xfb\x00\x36\xfe\x2d\x19\x23\x6e\x12\xd5\xfe\xa6\x12\xfe\x74\x16\xfd\x5a\x10\xfe\x00\x4b\x34\xfc\x85\x15\xfd\x1c\x24\x37"
"\x25\x1c\xaa\x10\xae\xb9\x1f\x4a\x00\x22\x22\x04\x23\x16\x02\x51\x0b\x00\x09\xe7\xf4\x02\xfc\x00\xe6\xf5\x7b\x25\xf2\xf1\x95\x03"
"\xe7\xf4\x18\xeb\xf0\x06\xe2\x11\xeb\xf0\x32\xaa\xeb\xf0\x09\xa0\x24\x4c\xeb\xf0\x0c\xa0\x24\x66\x2a\xeb\xf0\x0f\xa0\x24\x80\xeb"
"\xf0\x12\xfc\x00\xf2\xf1\x15\xee\xeb\xf0\x1e\x20\x00\x02\xa2\x22\x77\x2d\x54\x01\x10\x91\x27\xa3\x20\x9f\x21\xea\xf1\x05\x21\x00"
"\x93\x22\xe1\x25\x8a\xeb\xf0\x1b\x21\x00\x07\xe2\x12\x01\x32\x2a\x31\x00\x55\x35\x21\x00\x0a\x27\x3c\x4f\x21\x00\x0d\x27\x3c\x55"
"\x69\x21\x00\x10\x27\x3c\x83\x21\x00\x14\xd0\x21\x56\x03\x32\x00\x02\xf2\xf1\xf1\x21\x00\x20\xdc\x21\x60\xa3\x20\x21\x00\x81\x30"
"\x17\x38\x00\x33\x01\x3b\xe2\x11\xfe\x89\x00\x00\x11\x74\x6f\x6f\x6c\x2f\xff\x74\x65\x6d\x70\x2f\x69\x6e\x2e\xd6\xee\xf1\x00\x24"
"\xbd\x00\x00\xbc\x01\x00\x08\xff\x74\x6f\x70\x6c\x65\x76\x65\x6c\xfe\xc7\x31\x06\x53\x74\x72\x69\x6e\x67\x72\xc7\x31\x0c\xde\x33"
"\xde\x30\x65\x61\x6d\xc7\x31\xbf\x05\x63\x68\x61\x72\x73\xc7\x31\x04\xef\x65\x61\x63\x68\xc7\x31\x07\x70\x61\x5f\x74\x74\x65\x72"
"\x6e\xf2\xf1\x08\xff\x32\xe7\x73\x63\x61\x13\x43\x14\x46\x05\x73\x70\xf7\x6c\x69\x74\x22\x4c\x6d\x61\x74\x63\xd5\x68\x22\x4c\x70"
"\xfc\x30\x65\x14\x46\x02\x66\xfa\x21\x47\x0d\xe4\x32\x4d\x65\x6d\x6f\x72\xbd\x79\xef\x37\x04\x78\x70\x65\xe3\x32\x0e\xfe\xef\x33"
"\x45\x78\x65\x63\x75\x74\x6f\xfd\x72\xd9\x32\x70\x72\x65\x66\x69\x78\xee\x54\x43\x75\x74\x5f\xfe\x32\x06\x73\x75\xdd\x66\xa9\x44"
"\x04\x74\x6f\xb4\x43\x04\x67\x27\x73\x75\x62\x6a\x47\x6a\x4b\x03\xd0\x40\xc7\x31\xff\x09\x66\x69\x6c\x65\x6c\x6f\x63\x0e\xc3\x30"
"\x01\x03\x03"
);

}

XTAL_BIND2(Int){
	Xemb((

Int::times: method fiber{
	for(i: 0; i<this; ++i){
		yield i;
	}
}

Int::block_next: method{
	return (this==0 ? null : this-1), this;
}

Int::block_first: Int::block_next;

Int::op_eq#Int: method(v) this==v;
Int::op_lt#Int: method(v) this<v;

	),
"\xdf\x78\x74\x61\x6c\x02\xe8\xf3\x98\x00\xff\x30\x00\x02\x01\x4b\x00\x01\x00\xff\x23\x00\x4b\x00\x02\x00\x1c\xff\xff\x03\x00\x00"
"\x01\x06\xff\x1f\x02\xff\x01\x00\x1d\x00\x03\x00\x12\x00\xff\x07\xcd\xff\x00\x3d\x00\x00\xcd\xdf\x01\xff\x08\x00\xff\x0e\x05\xff"
"\xf6\xff\x00\x05\x00\x1b\xff\xf3\x00\x3c\x2b\xcd\x00\x38\x00\x01\x38\x02\x4a\x16\x00\x21\x00\xfe\xfa\xf4\x03\x00\x23\x02\x06\x03"
"\x03\x7f\xcd\x00\x02\x1e\x04\x03\x01\x15\x01\xff\x07\x00\x01\xcd\x03\x00\x1b\x00\xa5\x04\x66\x00\x02\x14\x02\x65\x01\x00\x6a\x00"
"\x08\xaf\x01\x06\x02\x03\x3e\x00\x0e\x12\x00\x03\xab\x01\x06\x38\x00\x02\x40\x04\x04\x48\x05\x02\xaa\xfb\xf1\x32\x70\x00\x04\x44"
"\x00\x05\x48\x08\x04\xff\x00\x13\x02\x06\x02\x1e\x03\xff\x70\x60\x0f\x3c\x05\xa2\x01\x44\x00\x08\x08\x02\x4a\x06\xa5\x05\xbc\x02"
"\x1f\xc2\x0f\xd4\x0e\x0b\xe6\x04\x0c\x12\x3c\x02\x51\x64\x00\xe8\xf3\x02\x00\x00\xe6\xf5\x33\x15\x22\xf2\xf1\x03\x34\x14\xaf\x00"
"\x4a\x16\x2b\xeb\xf0\x99\x00\x4a\xe9\xf2\x5f\xeb\xf0\x06\x00\x00\x35\x11\x7a\xeb\xf0\x01\x09\x70\x12\x35\x15\x33\x19\x6e\x10\x48"
"\x12\xe8\xf3\x35\x10\x42\x7f\x15\x05\xaf\x00\x4b\x12\xb4\x13\xe9\xf2\x08\x96\x10\x22\xb2\x1d\x2e\xaf\x00\x63\x12\x8b\x18\x62\xaf"
"\x00\x65\x00\x53\x00\x01\xb4\x14\x35\x11\x7d\xaf\x00\x0a\xef\x1a\xd4\x8b\x18\xdc\x14\x97\x70\x11\x0b\xeb\xf0\x11\x74\xff\x6f\x6f"
"\x6c\x2f\x74\x65\x6d\x70\xef\x2f\x69\x6e\x2e\xee\xf1\x00\x0d\x0e\xfc\xea\xf1\x3f\x21\x08\x74\x6f\x70\x6c\x65\xf7\x76\x65\x6c\x3f"
"\x21\x03\x49\x6e\x74\x7e\x3f\x21\x05\x74\x69\x6d\x65\x73\x3f\x21\xff\x0a\x62\x6c\x6f\x63\x6b\x5f\x6e\xeb\x65\x78\x58\x22\x0b\x68"
"\x23\x66\x69\x72\xad\x73\x58\x22\x01\x76\xf2\xf1\x08\x59\x22\x6f\x4f\x70\x5f\x65\x71\x88\x22\x88\x2a\x6c\x58\x22\x9f\x09\x66\x69"
"\x6c\x65\x69\x20\x3b\x20\x01\x03\x03\x03"
);

}

XTAL_BIND2(Float){
	Xemb((

Float::op_eq#Float: method(v) this==v;
Float::op_lt#Float: method(v) this<v;

	),
"\xdf\x78\x74\x61\x6c\x02\xe8\xf3\x3b\x00\xff\x30\x00\x02\x01\x4b\x00\x01\x00\xff\x13\x02\x06\x02\x1e\x03\xff\x01\xff\x1d\x00\x03"
"\x00\x07\x00\x01\xcd\xdf\x03\x00\x1b\x00\x04\x10\x00\x02\x00\xbd\x3c\x00\x00\x3c\x00\x00\x02\xfb\xf0\x00\x7f\x4a\x00\x05\x08\x02"
"\x1f\x01\xfa\xf4\x05\x02\x02\x02\x1f\x08\x07\x0c\x00\x15\x02\x26\x00\x1d\x0b\xef\x08\x08\x02\xcd\x2f\x01\x09\x00\x3c\x12\x64\x00"
"\x51\x16\x00\xe8\xf3\x02\x00\x00\xe6\xf5\x79\x05\x52\xf2\xf1\x03\x00\x00\x7b\x01\x1d\xeb\xf0\x06\x92\x02\x80\x7b\x05\x79\x09\x0c"
"\x00\xb5\x05\xeb\xf0\x7b\x00\xa1\x05\x05\xcb\x05\x00\x4c\x02\x01\xc5\x02\xd7\x02\x00\x20\x60\xd1\x00\x45\x01\xd8\x07\xad\x08\xc2"
"\x03\x00\x3a\x92\x01\xfd\x0b\xeb\xf0\x11\x74\x6f\x6f\x6c\x2f\xff\x74\x65\x6d\x70\x2f\x69\x6e\x2e\xce\xee\xf1\x00\x0a\x0e\xea\xf1"
"\x25\x11\x08\x74\x7f\x6f\x70\x6c\x65\x76\x65\x6c\x25\x11\xbf\x05\x46\x6c\x6f\x61\x74\x25\x11\x01\xf5\x76\xf2\xf1\x05\x37\x12\x6f"
"\x70\x5f\x65\xe9\x71\x47\x12\x47\x1a\x6c\x40\x12\x09\x66\x69\xdf\x6c\x65\x6c\x6f\x63\x21\x10\x01\x03\x01\x03"
);
}

XTAL_BIND2(Class){
	Xemb((

Class::ancestors: method{
	if(this===Any){
		return null;
	}			
	
	return fiber{
		this.inherited_classes{
			yield it;
			it.ancestors{
				yield it;
			}
		}

		yield Any;
	}
}

Class::members_ancestors_too: method{
	return fiber{
		this.members{
			yield it;
		}

		this.ancestors{
			it.members{
				yield it;
			}
		}
	}
}
),
"\xdf\x78\x74\x61\x6c\x02\xe9\xf2\x01\x87\xff\x00\x30\x00\x02\x01\x4b\x00\x01\xff\x00\xa4\x01\x06\x02\x30\x00\x03\xff\x01\x20\x03"
"\x02\x00\x1d\x00\x03\xff\x00\x07\x00\x01\x46\x00\x00\x3c\xff\xcd\x01\x00\x4b\x00\x02\x00\x91\xbf\x02\x06\x01\x38\x00\x04\x0c\x00"
"\x36\xff\x01\x02\x00\x05\x02\x00\xcd\x00\xbf\xfb\x07\xcd\x00\xfc\x07\x1a\x00\x4d\xf7\x00\x01\xfb\x0f\x01\x59\x00\x07\xcd\x7f\xfc"
"\x00\x3d\x00\x00\xcd\x01\x24\x00\x57\x06\x02\xfc\x2a\x07\xfd\x35\x00\xfe\x39\x03\xab\x02\xfd\x0f\x01\x16\x46\x00\xfe\x4a\x03\x00"
"\xbf\x36\xfd\x02\x00\x07\x01\x5d\x08\xfd\xff\x1d\xff\xf2\x00\x05\x00\x1b\xff\x7f\xef\x00\x4f\x00\x1f\x00\x4e\x3c\x00\xef\x03\x00"
"\x26\xff\x35\x00\x01\x07\xcd\xff\xff\x00\x37\xfd\x01\x00\x08\x01\x96\xf6\xf0\xcd\x10\x0e\x00\x07\x10\x01\xaa\x00\x25\xfb\x00\x51"
"\x9c\x00\x37\xfd\x00\x00\x09\x3c\xea\xf1\xb6\x00\x50\x00\x36\xfb\x7f\x04\x34\x05\xaf\xfb\x1d\xff\xaf\x92\x02\xac\x98\x06\x04\x12"
"\xa2\x09\xfb\xaf\x0f\xc1\x06\xfb\xcb\x09\x07\x00\x76\x04\x73\x3c\xcd\x17\x03\x3b\x11\x4a\x00\x06\x78\x02\xee\xfb\xf3\x03\x00\xd2"
"\x1c\x00\x04\x00\xcb\x12\x22\x02\x0a\x28\x09\x60\x08\x05\x6c\x0f\x7e\x0f\x90\x0e\x21\x06\xa2\x0f\x0e\x1f\xc6\x0d\x22\x02\x06\x28"
"\x0f\x3a\x02\x45\x07\x40\x02\x54\x60\x11\x54\x0f\x3a\x02\x08\x7c\x1f\x84\x8e\x1f\x90\x0e\x09\xb2\x1f\xc4\x1f\xc6\x0f\xd8\x0f\xff"
"\x15\xb4\x92\x02\xb1\x98\x06\x0a\xfc\x0f\x6e\x2f\x20\x1e\x2a\x3b\x1b\x0b\x4a\x14\x0c\x18\x02\x51\x48\x11\xe9\xf2\x50\xf1\x10\xe5"
"\xf6\x11\x35\xf2\xf1\x03\x12\x34\x11\xeb\xf0\x55\x04\x12\x34\xac\xeb\xf0\x0a\x12\x34\xaf\x3e\x36\x48\xc6\x20\x0c\x3e\x12\x33\x03"
"\xe7\xf4\xc6\x20\x05\x52\x34\x21\x05\x13\x30\x29\x32\x75\x32\xe8\xf3\x14\x49\x10\x35\x32\x22\x89\x38\xaf\x13\x30\x41\x32\x89\x38"
"\xb2\x49\x10\xac\x3b\x54\xf9\x20\xe1\xfa\x7f\xeb\xf0\x94\xeb\xf0\x9b\xeb\xf0\x15\x52\xeb\xf0\x67\xeb\xf0\x6e\xe7\xf4\xee\x31\xee"
"\x31\xa8\xea\xf1\xe2\x31\xe2\x31\xda\xeb\xf0\xef\xeb\xf0\xf6\x58\xe7\xf4\x12\x41\x12\x40\x01\x5c\xf6\xf0\x71\xf6\xf0\x55\x78\xf6"
"\xf0\x2f\xf6\xf0\x44\xf6\xf0\x4b\x6f\x34\xd0\x36\x41\x36\x40\xf4\xf2\x2a\x41\x71\x52\x31\x01\x86\xfa\x00\x00\x01\xce\x31\x11\x74"
"\x6f\x6f\x6c\xff\x2f\x74\x65\x6d\x70\x2f\x69\x6e\x9d\x2e\xee\xf1\x00\x0d\x0e\xea\xf1\x75\x41\x08\xff\x74\x6f\x70\x6c\x65\x76\x65"
"\x6c\x7e\x75\x41\x05\x43\x6c\x61\x73\x73\x75\x41\xef\x03\x41\x6e\x79\x75\x41\x11\x69\x6e\xff\x68\x65\x72\x69\x74\x65\x64\x5f\xf5"
"\x63\x8d\x41\x65\x90\x42\x0b\x62\x6c\x6f\xff\x63\x6b\x5f\x66\x69\x72\x73\x74\xfe\x75\x41\x09\x61\x6e\x63\x65\x73\x74\xeb\x6f\x72"
"\x90\x42\x0a\xb4\x43\x6e\x65\x78\x7c\xbe\x42\xb3\x44\x63\x61\x74\x63\x68\xaf\x48\xdf\x62\x72\x65\x61\x6b\x75\x41\x07\x6d\xaf\x65"
"\x6d\x62\x65\xcb\x43\x15\x01\x54\x5f\xf2\xc4\x46\x5f\x62\x40\xbf\x42\x66\x69\x6c\x65\x1c\xb5\x40\x71\x40\x01\x03\x03"
);

}

#ifndef XTAL_NO_THREAD

XTAL_BIND2(Mutex){
	Xemb((

Mutex::block_first: method{
	this.lock;
	return this;
}

Mutex::block_next: method{
	this.unlock;
	return null;
}

Mutex::block_break: method{
	this.unlock;
	return null;
}

),
"\xdf\x78\x74\x61\x6c\x02\xe8\xf3\x43\x00\xff\x30\x00\x02\x01\x4b\x00\x01\x00\xdf\x0e\x00\x06\x00\x36\xeb\xf0\x03\x01\x77\x00\xcd"
"\x00\x04\x00\x3c\xcd\x01\x12\x00\x5f\x00\x00\x4a\x00\x04\xeb\xf0\x01\xfa\xf4\xf7\x02\x00\x0f\x04\x04\x05\x01\x00\x1c\x5e\x1f\x00"
"\xe0\x00\x00\x3c\x00\x00\x3c\xeb\xf0\x25\x4a\x04\x00\x00\x14\x00\xfb\xf3\x03\x2a\x09\x0e\x00\xa9\x01\x0e\x00\x13\x07\x07\x48\x04"
"\x08\x12\x02\x51\x43\x00\x05\xe7\xf4\xf2\xf4\x84\x0a\xf2\xf1\x03\xe7\xf4\x09\x16\x30\x01\xe7\xf4\x2b\xeb\xf0\x71\x00\x1e\x02\x83"
"\x0f\x10\x1c\x02\xa0\x06\xbf\x02\xbf\x03\x05\x81\x00\xa1\x02\xbf\x05\x22\xeb\xf0\x19\x81\x00\x81\x02\xf5\x08\x2e\x81\x00\xb9\x02"
"\x68\xf5\x06\xf5\x08\xbc\x04\x42\x00\x00\x01\x0b\xeb\xf0\xff\x11\x74\x6f\x6f\x6c\x2f\x74\x65\xbf\x6d\x70\x2f\x69\x6e\x2e\xee\xf1"
"\x00\xf3\x09\x0e\xea\xf1\x55\x11\x08\x74\x6f\x70\xdf\x6c\x65\x76\x65\x6c\x55\x11\x05\x4d\xef\x75\x74\x65\x78\x55\x11\x04\x6c\x6f"
"\xdb\x63\x6b\x55\x11\x0b\x62\x76\x11\x5f\x66\xef\x69\x72\x73\x74\x55\x11\x06\x75\x6e\x3a\x76\x15\x0a\x7f\x13\x6e\x65\x78\x89\x12"
"\x7e\x14\xef\x62\x72\x65\x61\x79\x12\x09\x66\x69\x73\x6c\x65\x76\x10\x51\x10\x01\x03\x03"
);

}

#endif



XTAL_BIND2(Stream){
	Xemb((

Stream::match: method(pattern){
	exec: xpeg::StreamExecutor(this);
	if(exec.match(pattern)){
		return exec;
	}
	return null;
}

Stream::scan: method(pattern) fiber{
	exec: xpeg::StreamExecutor(this);
	while(exec.match(pattern)){
		yield exec;
	}
}

Stream::parse: method(pattern){
	exec: xpeg::StreamExecutor(this);
	if(exec.parse(pattern)){
		return exec;
	}
	return null;
}

Stream::split: method(pattern) fiber{
	exec: xpeg::StreamExecutor(this);
	if(exec.match(pattern)){
		yield exec.prefix;
		while(exec.match(pattern)){
			yield exec.prefix;
		}
		yield exec.suffix;
	}
	else{
		yield this.to_s;
	}
}

Stream::chars: method fiber{
	while(!this.eos){
		yield this.get_s(1);
	}
}

),
"\xdf\x78\x74\x61\x6c\x02\xe9\xf2\x01\x0f\xff\x00\x30\x00\x02\x01\x4b\x00\x01\xff\x00\x20\x01\x30\x00\x05\x00\x32\xfe\x00\x00\x06"
"\x01\x06\xff\x34\x00\x01\xfe\x13\x00\x07\x00\xfe\x00\x36\xff\x01\xff\x00\x07\x01\x00\xcd\x01\x00\x1d\xff\x00\x03\x00\x07\x00\x07"
"\xcd\xff\xbb\x00\x3c\x22\x00\x01\xcd\x00\x2e\x02\x3c\xa2\x34\x00\x4a\x28\x00\x21\x01\xfb\xf3\x02\x08\x00\x4b\x22\x26\x00\x2b\x04"
"\x03\x22\x00\x0d\x07\x28\x42\x02\x1b\x0b\x65\x15\x2a\x02\x3d\x42\x01\x68\x0f\xff\xf3\x06\x00\xa7\x1b\xff\xf0\x3a\x02\x37\x07\x0a"
"\x42\x08\x04\x2c\x02\x05\x5c\x0a\x07\xcd\x19\x03\x0d\x20\x0f\x32\x0c\xdd\x0d\x42\x08\x05\x00\x53\x50\x00\x06\x00\xf1\x4c\xc0\x0f"
"\x88\x0f\xe2\x00\x2f\x00\x38\x00\x93\x10\x01\x81\x0f\x1f\x07\x16\x3a\x1f\x8e\x0a\xf2\xea\x9c\x02\xef\x5c\x10\x11\x60\x15\x00\x1b"
"\x00\x77\x09\x01\x06\x5c\x10\x12\x02\x01\x88\x14\xba\xa3\x0b\x13\x42\x08\x07\x00\x27\x50\x00\x08\xf4\x02\x00\x93\x11\x14\x98\x10"
"\x1d\x00\x17\x00\xdf\x03\x01\x06\x02\x03\x6c\x01\x01\x01\xc7\x00\x15\x02\xdd\x01\x63\x13\xc5\x17\x05\xff\x55\xf1\x9e\x00\xee\xa2"
"\x0c\x16\x42\x04\x17\xea\x02\x09\x51\xb0\x01\xe9\xf2\x02\x4c\x00\xe6\xf5\x21\x25\xf2\xf1\x05\x03\x4c\x00\x01\xeb\xf0\x47\x10\xc0"
"\x10\x31\x00\xeb\xf0\x75\x2b\x00\x00\x0a\x3c\x22\x00\x00\x60\xeb\xf0\x55\x0b\x3a\x24\x86\xeb\xf0\x0e\x46\x24\x89\x00\x00\x55\x10"
"\x52\x24\xdf\xeb\xf0\x14\xe7\xf4\xe2\x7e\x26\x2c\x53\x23\x1f\x2b\x00\x09\xea\xf1\x03\xe7\xf4\x3d\x20\x3e\x3b\x23\x00\x00\x05\x05"
"\x00\xbc\x00\x3b\x20\x2c\xb5\x22\xc7\x22\x00\x2b\xc1\x20\x09\x46\x21\x3d\x20\x8c\xdd\x21\x3d\x21\x2e\x06\x4f\x24\xdd\x23\xe9\xf2"
"\x63\xaa\xc1\x20\x0c\xc5\x2c\x89\xc1\x20\x0f\xd9\x2c\x8c\x08\xe9\x20\x75\x22\xf1\x28\xe2\xc1\x20\x81\x22\x93\x25\xeb\xf0\xa3\xe5"
"\x06\x3a\x3d\x41\x38\x90\x23\x01\x69\x22\x0b\xfe\xeb\xf0\x11\x74\x6f\x6f\x6c\x2f\x74\x7f\x65\x6d\x70\x2f\x69\x6e\x2e\xee\xf1\xe7"
"\x00\x18\x0e\xea\xf1\x8d\x31\x08\x74\x6f\xbf\x70\x6c\x65\x76\x65\x6c\x8d\x31\x06\xbf\x53\x74\x72\x65\x61\x6d\x8d\x31\x07\x7f\x70"
"\x61\x74\x74\x65\x72\x6e\xf2\xf1\x7d\x05\x8d\x31\x04\x78\x70\x65\x67\x8d\x31\xfd\x0e\xa4\x33\x45\x78\x65\x63\x75\x74\xfb\x6f\x72"
"\x8d\x31\x05\x6d\x61\x74\x63\x39\x68\xb6\x32\xb6\x37\x73\x63\x61\xb5\x33\xb6\x36\xbf\x05\x70\x61\x72\x73\x65\xe1\x3b\x06\xbf\x70"
"\x72\x65\x66\x69\x78\x9f\x32\x73\xfb\x75\x66\x1a\x44\x04\x74\x6f\x5f\x73\xbe\xd7\x32\x73\x70\x6c\x69\x74\x8d\x31\x03\xbb\x65\x6f"
"\x30\x43\x67\x65\x74\x2f\x44\x63\xf9\x68\x04\x40\x8d\x31\x09\x66\x69\x6c\x65\x77\x6c\x6f\x63\x89\x30\x01\x03\x03"
);

}

namespace debug{
	
XTAL_BIND2(Debug){
	Xemb((

debug::scope: singleton{
	op_call{
		return this;
	}

	block_first{
		debug::enable();
		return this;
	}

	block_next{
		debug::disable();
		return null;
	}

	block_break{
		debug::disable();
	}
}
	),
"\xdf\x78\x74\x61\x6c\x02\xe8\xf3\x69\x00\xff\x30\x00\x02\x02\x47\x00\x00\x02\xff\x01\x00\x00\x03\x01\x00\x01\x00\x5d\x49\xeb\xf0"
"\x08\x00\x03\xfc\xf0\x4b\x08\x00\xff\x08\x00\x06\x00\x3c\x3a\x01\x00\x75\x3c\x04\x01\xcd\x09\x01\x01\x00\x09\x10\x04\x6f\x02\x00"
"\x10\x01\xfb\xf0\x00\x32\x08\x00\x97\x0b\x00\x34\xeb\xf0\x01\x1a\x01\x08\x00\x3c\xfd\xcd\x23\x05\x02\x00\x0a\x00\x03\xcd\x4e\x13"
"\x01\x03\x00\x11\x38\x03\x26\x00\x0d\x42\x04\xe7\x01\xcd\x00\x4e\x00\x4d\x09\x03\x00\x0c\xce\x5c\x04\x04\x00\x0d\x66\x0e\x4f\x07"
"\x04\x00\xfd\x0e\x5c\x01\x01\x48\x00\x4a\x00\x0f\xbb\x00\x00\x26\x00\x30\x00\x10\x7a\x02\x51\xc3\x00\x07\xe7\xf4\xf2\xf4\xd0\x0a"
"\xf2\xf1\x03\x00\x95\x05\xee\x00\x00\x6e\x00\x00\x5a\x00\xe8\xf3\x1c\x4a\xeb\xf0\x0b\xe7\xf4\x33\xf2\x04\xea\xf1\x4b\xeb\xf0\x14"
"\xbd\x00\xd2\x04\x02\xf2\xf0\x08\xeb\xf0\xf1\x01\x2b\x11\xc0\xce\x0f\x2d\x13\x10\x00\xe8\xf3\x03\x00\x56\x14\x00\x10\x28\xf1\x00"
"\xf9\x02\x58\x12\x09\xe9\xf2\x1f\xf1\x00\x05\x12\x44\x58\x12\xf9\x03\x36\xf1\x00\x11\x12\x58\x12\x0c\xe9\xf2\x11\x4e\xf1\x00\x1d"
"\x12\x58\x12\x0e\x5a\x16\xe6\xf5\x58\x11\xf9\x68\x74\x01\x05\x11\x11\x74\x6f\x6f\x6c\xff\x2f\x74\x65\x6d\x70\x2f\x69\x6e\xcd\x2e"
"\xee\xf1\x00\x11\xad\x11\xac\x12\x08\x74\x7f\x6f\x70\x6c\x65\x76\x65\x6c\xad\x11\xbf\x05\x64\x65\x62\x75\x67\xad\x11\x0f\xff\x61"
"\x75\x74\x6f\x5f\x69\x6e\x69\x7f\x74\x69\x61\x6c\x69\x7a\x65\xad\x11\x7f\x07\x6f\x70\x5f\x63\x61\x6c\xf1\x12\xff\x0b\x62\x6c\x6f"
"\x63\x6b\x5f\x66\xaf\x69\x72\x73\x74\xad\x11\x0a\x21\x23\x6e\xf3\x65\x78\x2b\x22\x20\x24\x62\x72\x65\x61\x55\x6b\xf2\xf1\x05\xf2"
"\xf1\x06\xf2\xf1\x07\xad\x11\x7f\x06\x65\x6e\x61\x62\x6c\x65\xf2\xf1\x5d\x08\x10\x22\x64\x69\x73\x61\x25\x09\xf2\x12\xef\x73\x63"
"\x6f\x70\x0f\x22\x09\x66\x69\x73\x6c\x65\x22\x20\xdc\x10\x01\x03\x03"
);
}

}

XTAL_BIND2(Iterator){
	Xemb((

Iterator::to_fiber: method(){
	return fiber{
		this{
			yield it;
		}
	}
}

Iterator::scan: method(pattern) fiber{
	exec: xpeg::IteratorExecutor(this);
	while(exec.match(pattern)){
		yield exec;
	}	
}

Iterator::ip: method(n:3){
	m: MemoryStream();
	m.put_s("<[");
	a: this.take(n+1)[];
	m.put_s(a.take(n).join(","));
	if(a.length==n+1){
		m.put_s(" ...]>");
	}
	else{
		m.put_s("]>");
	}
	m.to_s.p;
	return chain(a.each, this);
}

Iterator::op_to_array: method{
	ret: [];
	this{
		ret.push_back(it); 
	}
	return ret;
}

Iterator::op_to_map: method{
	ret: [:];
	this{ |key, value|
		ret[key] = value; 
	}
	return ret;
}

Iterator::join: method(sep: ""){
	ret: MemoryStream();
	if(sep==""){
		this{
			ret.put_s(it.to_s);
		}
	}
	else{
		this{
			if(!first_step){
				ret.put_s(sep);
			}
			ret.put_s(it.to_s);
		}
	}
		
	return ret.to_s;
}

Iterator::with_index: method(start: 0) fiber{
	i: start;
	this{
		yield i, it;
		++i;
	}
}

Iterator::collect: method(conv) fiber{
	this{
		yield conv(it);
	}
}

Iterator::map: Iterator::collect;

Iterator::select: method(pred) fiber{
	this{
		if(pred(it)){
			yield it;
		}
	}
}

Iterator::filter: Iterator::select;

Iterator::break_if: method(pred) fiber{
	this{
		if(pred(it))
			break;
		yield it;
	}
}

Iterator::take: method(times){
	if(times<=0){
		return null;
	}

	return fiber{
		i: 0;
		this{
			yield it;
			i++;

			if(i>=times){
				break;
			}
		}
	}
}

Iterator::zip: method(...args){
	return builtin::zip(this, ...args);
}

Iterator::chain: method(...args){
	return builtin::chain(this, ...args);
}

Iterator::cycle: method fiber{
	temp: [];
	this{
		temp.push_back(it);
		yield it;
	}
	
	for(;;){
		temp{
			yield it;
		}
	}
}

Iterator::max_element: method(pred: null){
	item: null;
	if(pred){
		this{
			if(item){
				if(pred(it, item))
					item = it;
			}
			else{
				item = it;
			}
		}
		return item;
	}

	this{
		if(item){
			if(item<it)
				item = it;
		}
		else{
			item = it;
		}
	}
	return item;
}

Iterator::min_element: method(pred: null){
	item: null;
	if(pred){
		this{
			if(item){
				if(pred(it, item))
					item = it;
			}
			else{
				item = it;
			}
		}
		return item;
	}

	this{
		if(item){
			if(item>it)
				item = it;
		}
		else{
			item = it;
		}
	}
	return item;
}

Iterator::find: method(pred){
	this{
		if(pred(it)){
			return it;
		}
	}
}

Iterator::inject: method(init, fn){
	result: init;
	this{
		result = fn(result, it);
	}
	return result;
}

Iterator::with_prev: method fiber{
	prev: undefined;
	this{
		yield prev, it;
		prev = it;
	}
}

	),
"\xdf\x78\x74\x61\x6c\x02\xe9\xf2\x07\x82\xff\x00\x30\x00\x02\x01\x4b\x00\x01\xff\x00\x4d\x00\x4b\x00\x02\x00\x46\xff\x01\x06\x00"
"\x36\x01\x02\x00\x03\x7e\xf2\xf1\xfd\x07\x00\x00\xfe\x07\x00\x02\xff\x01\xfd\x1d\x00\x03\x00\x16\x00\xff\x07\x00\xfe\x00\x3d\x00"
"\x00\xcd\xff\x01\x00\x36\xfd\x02\x00\x04\x01\xab\x00\xcd\x15\x00\xcd\x19\x00\xcd\x21\x00\xff\xff\xf2\x00\x05\x00\x1b\xff\xef\x00"
"\xdf\x4f\x00\x1f\x00\x4e\x02\x00\x02\x00\xfb\x26\xff\x3d\x00\x01\x07\xcd\xff\x00\xff\x37\xfd\x01\x00\x05\x01\x00\x00\xdf\x01\xcd"
"\x10\x00\x1d\x28\x00\x03\x00\xee\x5f\x01\x25\x00\x51\x52\x00\x37\xfd\x00\xf3\x00\x06\xea\xf1\x6c\x00\x50\x00\x3c\xcd\x15\x00\x8c"
"\x00\x01\x8c\x02\x4a\x28\x00\x2f\x01\xfb\xf3\xf7\x03\x00\x32\x04\x00\x04\x00\x2b\x01\xdf\x30\x00\x0a\x00\x32\x30\x00\x0b\x01\x5f"
"\x06\xff\x34\x00\x01\xbf\x00\x28\x2e\x03\xaf\xff\x01\x00\x0c\x38\x00\x01\x6e\x00\x03\x63\x00\x15\x74\x02\x2d\x02\xc2\x0f\xff\xf3"
"\x48\x02\xf5\xf0\x8c\x0c\x0d\x9c\x08\x05\x00\x5f\xfd\x7d\x23\x24\x00\x05\xfd\x03\xcd\x03\xfa\xf0\xd3\x10\xfe\xbd\x00\x00\x00\x02"
"\x00\x00\x39\x00\xff\x11\x00\xfe\x01\x06\x03\x03\xcd\xdf\x01\x02\x0d\x03\xfd\xac\x00\x36\x01\xef\x01\x00\x12\x02\x2f\x00\xff\x38"
"\x00\x3d\x13\x2d\x10\x07\xcd\xfd\x01\xc9\x01\x49\x12\x93\x02\x02\x06\x00\x45\x11\x14\x4a\x11\x32\x14\x38\x6f\x00\x15\x02\xff\x3a"
"\x17\x01\x1e\x11\x00\x6a\x23\x01\x0a\x06\x00\x03\x32\x13\x00\x1b\x28\x00\xfc\x35\x00\x94\x14\x38\x00\x16\x01\xfe\x00\xe5\x36\xeb"
"\xf0\x17\x38\x01\xb0\x00\x18\x02\x38\xff\x00\x19\x03\xff\x03\x06\x00\x34\xe9\x01\x61\x11\x91\x07\x1a\x9c\x08\x06\x00\x4b\xa3\xfc"
"\x42\x0a\x07\x3a\x07\x02\x00\x03\x22\x05\xcd\x1d\xfe\x32\x10\x1b\x00\xfc\x32\x0f\x44\x0f\xac\x00\xb8\x59\x0f\x6b\x0f\x7d\x0d\x07"
"\xcd\xfc\x90\x08\x13\xbe\x9c\x08\x07\x00\x4d\xfb\x44\x0a\x02\x03\x52\xec\x13\xfc\x19\x20\x18\x20\x01\x1c\x20\x02\x02\x00\x7b\x05"
"\xfc\x23\x02\xfb\x1a\xfe\xfd\x8e\x00\xa7\x36\xfc\x03\x12\x23\x94\x29\xfc\x21\x2f\x06\x52\x34\x29\xfc\x41\x2f\x53\x26\xfc\x5d\x2b"
"\xfb\x90\x08\xbd\x1c\x9c\x08\x08\x00\xad\xfb\x1b\x12\xfb\xc9\x02\x48\x00\x25\x10\xfc\x29\x12\x0e\x00\x05\xfb\x4b\x1e\x02\xd1\x03"
"\x47\xe6\x1f\xf8\x12\x07\x22\x02\xa1\x17\xa8\x14\x33\x11\x0d\x2f\x1f\x21\xf1\x48\x02\xee\xe2\x4e\x06\x08\x34\x2f\xec\x2f\x7c\x0e"
"\x1b\x00\x50\xbc\x4e\x3f\xf8\x12\x09\xff\x01\xcd\xfd\x13\x21\x13\xff\x1d\x28\x30\xb9\x31\xfb\x72\x34\x6d\x3f\x15\x28\xaa\xee\x30"
"\x02\x20\x20\xe7\x48\x02\xe4\x4e\x06\x0a\xa0\x9e\x3f\xb0\x3f\x7c\x0e\xa9\x11\x6b\x29\x14\x9c\x08\x09\xb7\x00\x59\xfc\x1b\x12\xfc"
"\x03\x8e\x00\x4b\x46\xb2\x00\x4d\xfc\xc3\x02\xd6\x3f\xf8\x12\x0b\x22\x02\x71\x1a\x68\x21\x44\x40\x2b\x03\x02\xfc\x08\x12\x4f\x2a"
"\x1e\x22\xee\x48\x02\xeb\x4e\x06\x0c\x3e\x4f\x50\x4f\x74\x7c\x0f\x8e\x0a\x21\x9c\x08\x0b\x00\x53\x04\x00\xa7\x0c\x00\x4c\xa8\x4f"
"\xf8\x12\x0d\x22\x02\x1c\x84\xe2\x03\x54\x10\xfe\xc4\x11\x0e\x00\x2d\x0f\x1b\x25\xec\x0a\x48\x02\xe9\x4e\x06\x0e\xfe\x4f\x10\x5f"
"\x22\x5f\x8e\x0a\x55\x24\x9c\x05\x02\xfb\xf1\x32\x9e\x20\x24\x98\x00\xdd\x25\x9c\x08\x0d\x00\x58\x04\x00\x0e\x00\x89\x51\x56\x5f"
"\xf8\x12\x0f\xf2\x33\x74\x5e\x23\x01\x08\x10\x04\x22\x85\x5f\x1b\x25\x2d\x4d\x10\xb0\x5f\xc2\x5f\xd4\x5f\xa8\x8e\x0a\xc3\x03\xf9"
"\x59\x28\x98\x00\x29\x9c\x08\x0f\x3b\x00\x5a\x04\x00\x10\x00\x53\x1e\x6f\xf8\x12\x35\x11\x22\x02\x23\x3c\x6f\x00\x18\x48\x01\xd6"
"\x02\x54\x55\x6f\x19\x27\xe5\x48\x02\xe2\x4e\x06\x12\x82\x6f\xe8\x94\x6f\xa6\x6f\x8e\x0a\x2c\x9c\x08\x11\x00\x66\xbd\x01\x99\x40"
"\x01\x1f\x02\xfc\x6e\x74\x01\x8a\x8e\x04\x4b\x56\x70\x54\x98\x41\xf0\x6f\xf8\x12\x13\x62\x22\x02\x22\x28\x77\xd4\x41\xe2\x03\xfc"
"\x1f\x46\x32\xe5\x05\x76\x20\x1b\x80\x60\x33\x7f\x1d\xff\xe6\x0a\x48\x02\xe3\x4e\x06\x14\x58\x7f\x6a\x7f\x7c\x7f\x8e\x0a\x75\x12"
"\x9c\x08\x13\x6a\x10\x30\x00\x31\x00\x62\x2f\x32\x02\x06\x03\x37\x81\x35\x3f\x31\x42\x80\x54\x93\x01\x93\x05\x32\x9c\x08\x14\x80"
"\x88\x18\x8c\x8f\xba\x92\x06\x18\x9c\x08\x15\x00\x95\x04\x00\x16\x13\x00\x8e\xe4\x1f\xf6\x14\x15\x22\x02\x9b\x10\x06\x26\x54\x29"
"\x7f\x17\x29\xed\x48\x02\xea\x4e\x06\x16\x30\x8f\x8c\x42\x8f\x54\x8e\x36\xfc\x0f\x00\x14\x29\x02\x00\x17\x10\xfe\x18\x1f\x9f\x1b"
"\x2f\x51\x03\x18\x4a\x9f\x5c\x9f\xc2\x3f\xeb\xff\xc0\x8c\x0c\x35\x9c\x08\x17\x00\xb0\x54\x2c\x34\xb9\x70\xfc\xb9\x70\xfb\x23\x01"
"\x56\xf2\x8f\x2a\xf8\x12\x19\x22\x02\x24\xa4\x22\x11\xca\x41\x54\x10\x5f\xfc\x00\x34\xfb\x01\x46\x34\x09\x94\x20\x92\x99\x11\x04"
"\x6c\xa2\xa5\x9f\x1d\x32\x40\x49\x01\xe1\x02\x4e\x06\x1a\xca\x9f\xdc\x9f\x58\x2f\x6a\x23\x34\xaf\xf8\x12\x75\x1b\x22\x02\x1f\xa4"
"\x22\x0c\xfc\x1f\xac\x10\xa4\x67\xaf\x79\xaf\x1d\xa4\x50\x49\x01\xe6\x4e\x06\x1c\x50\x9e\xaf\xb0\xaf\xc2\xaf\x6a\x2a\x38\x9c\x08"
"\x18\x1e\xaf\x04\x30\xaf\xf4\x16\x1d\x4c\xaf\x5e\xaf\x0c\xbf\x82\xaf\x4e\x06\x41\x1e\x3a\xbf\x4c\xbf\x5e\xbf\xd4\xaf\xf2\x18\x1f"
"\xf2\xa9\x43\xfe\x1f\x76\x40\xd3\xbf\xe5\xbf\x27\xbf\x20\x0a\xcf\x28\x1c\xcf\x2e\xcf\x6a\x2a\x3b\x9c\x08\x19\xd4\x3f\xf6\x14\x35"
"\x21\x22\x02\x20\xca\x42\x34\xfc\xbf\x00\x8a\x14\xca\x05\x21\x4f\x24\x00\x4e\x90\x02\x81\xcf\x1d\xff\x15\xe8\x48\x02\xe5\x4e\x06"
"\x22\xa6\xcf\xb8\xcf\x54\x8f\xba\x96\x02\x3e\x9c\x08\x1a\x00\x4e\x94\x20\xfa\x54\xf8\xcf\xf8\x12\x23\x22\x02\x18\xc6\x45\xfc\xcd"
"\xb1\x50\xaf\x20\x36\xdf\xfa\x00\x49\x01\xed\x4e\x06\x24\x5a\xdf\xa8\x6c\xdf\xca\xcf\x6a\x2a\x43\x9c\x08\x1b\x4e\x52\x1c\x23\x00"
"\x4c\x96\xb0\x45\xcf\xf7\x13\x25\xc0\x4f\xc4\x20\x08\x7d\xcf\xe7\x4f\x53\x01\x26\xfa\xdf\x0c\xef\x7e\xdf\x8e\x0a\x95\x44\x9c\x04"
"\x45\x90\x02\x51\x08\xc0\xe8\xf3\x02\xa0\xd6\xe3\x02\xfa\xf2\xf1\x8d\x20\xe9\xf2\x05\x1c\xf8\x55\x2a\xeb\xf0\x08\x2a\x12\x00\x16"
"\x60\x01\xb2\x00\x3b\xf1\x97\x00\x00\x8d\xeb\xf0\x0e\xb6\x71\xeb\xf0\xf2\x88\xeb\xf0\x79\xc0\xea\xf1\x01\x3d\xe0\x1c\x30\x27\xf1"
"\x00\x63\x01\x96\xeb\xf0\x01\x81\xbc\xe0\x02\x49\xeb\xf0\xa9\x1f\xac\x00\x77\xf1\x51\x00\x00\x21\x5c\xf3\x02\xb5\xa8\xeb\xf0\x22"
"\x50\xf3\x02\xab\x00\x00\x24\xd6\x20\xf3\x03\x0c\xeb\xf0\x26\x50\xf3\x03\x0f\xaa\x00\x00\x28\xa4\xf4\x75\xeb\xf0\x2a\xb0\xf4\x78"
"\xaa\x00\x00\x2c\xa4\xf4\xd5\x3c\xf0\x2d\x80\xf3\x03\xb5\xe3\x00\x00\x2f\x5c\xf3\x04\x41\x3c\xf0\x2f\x96\x38\xf3\x04\x5b\x3c\xf0"
"\x33\xf8\xf4\xc3\xf1\x35\x5a\xec\xf4\x78\x0c\x07\x05\x10\x3c\xf0\x36\x74\xf3\x6b\x05\xc6\x3c\xf0\x39\x74\xf3\x06\x7c\x3c\xf0\x2d"
"\x3c\x80\xf3\x06\xd2\x3c\xf0\x3f\xd6\xe0\x1b\xf0\x2b\x07\x26\x3c\xf0\x44\x5c\xf3\x07\xdb\x60\x56\x04\x80\x45\xf3\x05\xfb\xc2\xe0"
"\x1c\xf2\x0d\xf3\x37\x01\x44\xf4\x05\x90\x27\xf0\x1f\xf2\xb3\xf1\x0c\xf4\x08\xd7\xe0\x9a\x0d\x58\xe2\x27\xf0\x09\x3c\x32\x67\x02"
"\xc6\x01\x00\x5b\x06\x28\x41\xf4\xc7\x03\x2e\xf2\x90\x27\xf0\x0f\xb6\x71\x9f\x04\x42\x3b\xf1\xf5\x27\xf0\x5b\xf2\xfb\xf1\x85\x04"
"\x46\x27\xf0\x28\x67\xf2\x2b\x01\x85\x04\x99\x27\xf0\x1e\x74\xf1\x17\x14\x8a\x77\xf1\x4c\x27\xf0\x20\x80\xf1\x03\x14\x77\xf1\x54"
"\x18\xd3\x00\x8b\xf2\x03\x17\x02\xab\x27\xf0\x93\x41\xee\x04\xc6\x2a\x11\x02\xae\xd3\x00\xa3\xf2\x9f\x07\x03\x0f\x1a\x27\xf0\x27"
"\x63\x1b\x03\x12\xd3\x00\xbb\xf2\x7b\x18\x15\x78\x27\xf0\x2b\x8b\x1c\x7b\xd3\x00\xd3\xf2\x7b\x18\x25\xd8\x27\xf0\x2e\x3b\x17\xee"
"\x02\xe6\xd3\x00\xeb\xf2\x1e\x03\x17\x04\x44\x05\x02\x36\x30\xc4\x06\xee\xf2\x81\x5e\xff\x10\x3b\x33\x08\x27\xae\x11\x0f\x02\xf3"
"\x18\x7b\xac\xd7\xe0\x2a\x2c\x05\x13\x27\xf0\x37\x27\x1b\x05\xb5\xc9\x27\xf0\x3a\x27\x1b\x06\x7f\x27\xf0\x3d\x16\xdb\x1b\x06\xd5"
"\x27\xf0\x41\x4c\x01\x8b\x02\xcc\x60\x30\x5c\x01\x27\xf0\x63\x02\x03\x17\x07\x2c\xd7\xe0\xa2\x2b\x29\x27\x74\x07\x2e\xf2\x2d\x3c"
"\xf0\x42\x3c\xf0\x7b\xf1\x58\x2f\xf1\xd8\x21\xd8\x20\x01\x1b\xbd\xe0\x30\xbd\xe0\x51\x37\x85\x04\xf0\x21\xf0\x21\x6e\xbd\xe0\x83"
"\xbd\xe0\x51\x8a\x85\x04\x08\x31\x08\x31\xd0\xbd\xe0\xe5\xbd\xe0\x31\xec\x85\x04\x20\x31\x20\x30\x02\x20\x05\xf0\x11\xa0\xa3\x02"
"\x3c\x0d\xf4\x38\x31\x38\x31\x80\x05\xf0\x95\xa2\x05\xf0\x9c\x0d\xf4\x50\x31\x50\x31\xd9\x05\xf0\xee\xa2\x05\xf0\xf5\x0d\xf4\x68"
"\x31\x68\x30\x03\xd8\x20\x03\x45\x57\x1d\xf0\x5e\x7f\x14\x80\x31\x80\x31\xad\x1d\xf0\xc5\xc2\x1d\xf0\xc9\x7f\x14\x98\x31\x98\x30"
"\x04\x19\x82\xf0\xf0\x2e\xf0\xf0\x11\xa0\xee\xf2\xb0\x31\xb0\x31\xa6\x82\xf0\xf0\xbb\xf0\xf0\x98\x30\xee\xf2\xc8\x31\xc8\x31\xe6"
"\x82\xf0\xf0\xfb\x25\xf0\x1b\xf1\xef\xf1\xe0\x30\xdf\x32\x50\x8a\x25\xf0\x65\x25\xf0\x6c\x47\x24\xf8\x31\xf8\x31\x9e\x8a\x25\xf0"
"\xb3\x25\xf0\xba\x47\x24\x10\x41\x10\x40\x06\x1a\xd7\xe0\x06\xec\x20\x06\x22\x0d\xf3\x27\x42\x28\x41\x15\x54\x83\xd0\x69\x83\xd0"
"\x70\x2d\x44\x40\x41\x40\x41\x15\xae\x83\xd0\xc3\x83\xd0\xca\x2d\x44\x58\x41\x58\x41\x15\xfe\x50\x00\x13\x50\x00\x1a\xab\x24\x70"
"\x41\x70\x41\x9a\x80\x30\x07\xfc\x30\x07\x73\xab\x24\x88\x41\x6c\xd6\x3a\xf1\x07\x81\x04\x01\x0b\x3c\xf0\x11\x74\xff\x6f\x6f\x6c"
"\x2f\x74\x65\x6d\x70\xff\x2f\x69\x6e\x2e\x78\x74\x61\x6c\xe7\x00\x46\x0e\x2f\xf1\xbb\x41\x08\x74\x6f\xbf\x70\x6c\x65\x76\x65\x6c"
"\xc0\x42\x49\x7f\x74\x65\x72\x61\x74\x6f\x72\xbb\x41\xff\x0b\x62\x6c\x6f\x63\x6b\x5f\x66\xaf\x69\x72\x73\x74\xbb\x41\x0a\xdf\x43"
"\x6e\xf3\x65\x78\xe9\x42\xde\x44\x63\x61\x74\x63\x7d\x68\xda\x48\x62\x72\x65\x61\x6b\xc0\x44\xf6\xe4\x40\x62\x65\xd9\x42\x07\x70"
"\x61\x74\xea\xd3\x40\x6e\x1b\xf1\x0a\xbb\x41\x04\x78\x70\xeb\x65\x67\xbb\x41\x10\xd2\x45\x45\x78\x65\xdb\x63\x75\xd7\x44\x05\x6d"
"\x05\x55\x04\x73\x57\x63\x61\x6e\xbb\x41\x01\x31\x52\x0f\xbb\x41\xff\x0c\x4d\x65\x6d\x6f\x72\x79\x53\xf5\x74\x15\x50\x6d\x55\x52"
"\x70\x75\x74\x5f\xbd\x73\x37\x52\x74\x61\x6b\x65\xda\x42\x6f\xfb\x70\x5f\x1e\x50\x61\x72\x72\x61\x79\xee\x37\x52\x6a\x6f\x69\x67"
"\x52\x06\x6c\x65\xc7\x6e\x67\x74\x5e\x53\x1e\x50\x8d\x52\x01\x70\xee\x55\x52\x63\x68\x61\xae\x53\x04\x65\x61\xf6\x07\x53\x02\x69"
"\xc9\x52\x09\x70\x75\x73\x5f\x68\x5f\x62\x61\x63\x18\x52\x09\x9c\x53\x7b\x6d\x61\xc9\x52\x03\x73\x65\x70\x1b\xf1\x7d\x1d\x55\x52"
"\x73\x74\x61\x72\x74\x1b\xf1\xfd\x1e\xea\x42\x77\x69\x74\x68\x5f\x69\xef\x6e\x64\x65\x78\x37\x52\x63\x6f\x6e\xf5\x76\x1b\xf1\x20"
"\x26\x52\x63\x6f\x6c\x6c\xeb\x65\x63\xe9\x42\x03\xfd\x54\x04\x70\x72\x6b\x65\x64\x1b\xf1\x23\xb0\x52\x73\x65\x41\x65\x8f\x06\x66"
"\x69\x6c\xd3\x40\x56\x62\x56\x66\x08\xee\x14\x52\x5f\x69\x66\x55\x52\x74\x69\x6d\xeb\x65\x73\x1b\xf1\x27\x37\x52\x61\x72\x67\x9a"
"\x91\x62\x28\x26\x52\x62\x75\x6c\x60\xae\x53\x03\xeb\x7a\x69\x07\x62\x28\xa0\x66\x05\x63\x79\xf7\x63\x6c\x65\x71\x6b\x0b\x6d\x61"
"\x78\x9d\x5f\x61\x60\x6d\x65\x6e\x16\x62\xd1\x69\x69\xc9\x6e\xdf\x6f\x37\x52\x66\x26\x60\x37\x52\x69\x6e\xad\x69\xe9\x42\x02\x66"
"\x31\x52\x2f\x1b\xf1\x30\x2e\xb0\x52\x69\x6e\x6a\x42\x64\x09\x21\x62\x52\x60\xc9\x76\xe4\x52\x6b\x60\x65\xe0\x40\xb7\x40\x06\x03"
"\xd6\xdd\x52\x3c\x5b\x68\x52\x2c\xa3\x41\x06\x20\xdf\x2e\x2e\x2e\x5d\x3e\xdd\x52\x5d\x3e\x06\x1b\xf1\x02\x03"
);

	Xfor3(primary_key, secondary_key, value, it->members()){
		XTAL_UNUSED_VAR(value);
		if(!XTAL_detail_raweq(Xid(p), primary_key) && !XTAL_detail_raweq(Xid(each), primary_key)){
			cpp_class<Iterable>()->def(unchecked_ptr_cast<ID>(primary_key), xnew<DelegateToIterator>(unchecked_ptr_cast<ID>(primary_key)), secondary_key, 0);
		}
	}	
}

XTAL_BIND2(CompileError){

	Xemb((
builtin::CompileError::initialize: method(message, errors:[]){
	Exception::initialize(%f"%s\n%s"(message, errors.join("\t\n")));	
}
	),
"\xdf\x78\x74\x61\x6c\x02\xe8\xf3\x2d\x01\xff\x30\x00\x02\x00\x32\x45\x01\x00\xff\x03\x01\x4b\x00\x01\x00\x1f\xff\x7f\x23\x00\x03"
"\x00\x04\xff\x42\xfa\xf0\xff\x08\x00\x32\xcd\x01\x00\x09\x02\xff\x02\x00\x01\x03\x07\xff\xfe\x05\xff\x02\x00\x02\x04\x36\xff\x01"
"\x00\xff\x0a\x05\x00\x00\x01\x01\x34\x02\xdf\x01\x02\x03\x00\x34\x2f\x01\x00\x3c\xee\xeb\xf0\x4a\x00\x09\xeb\xf0\x01\x00\x30\x3b"
"\x00\x0b\x3e\x00\x01\x00\x51\x0c\x00\xe8\xf3\xb0\x25\x00\xe5\xf6\x5d\x05\x2e\x00\x00\x04\x5c\x02\x01\x40\x56\x0f\x5b\x01\xeb\xf0"
"\x55\x05\x7b\x00\x79\x05\x08\x2e\x00\x99\x06\x5c\x01\x9d\x02\x00\x01\x79\x07\x97\x06\x00\xed\x2c\x06\x00\x01\x0b\xeb\xf0\x11\x74"
"\x6f\xff\x6f\x6c\x2f\x74\x65\x6d\x70\x2f\x77\x69\x6e\x2e\xee\xf1\x00\x0c\x0e\xea\xf1\xfe\xe9\x01\x08\x74\x6f\x70\x6c\x65\x76\xfb"
"\x65\x6c\xe9\x01\x07\x62\x75\x69\x6c\xf7\x74\x69\x6e\xe9\x01\x0c\x43\x6f\x6d\xff\x70\x69\x6c\x65\x45\x72\x72\x6f\xfd\x72\xfb\x02"
"\x6d\x65\x73\x73\x61\x67\xad\x65\xe9\x01\x06\x65\x14\x11\x73\xf2\xf1\x06\xfa\xf2\xf1\x07\xe9\x01\x09\x45\x78\x63\x65\xef\x70\x74"
"\x69\x6f\x06\x12\x0a\x69\x6e\x7f\x69\x74\x69\x61\x6c\x69\x7a\x23\x12\xb7\x04\x6a\x6f\x05\x13\x09\x66\x10\x10\x6c\xdb\x6f\x63\xe5"
"\x00\x03\x03\xd1\x01\x05\x25\xef\x73\x0a\x25\x73\xe9\x01\x02\x09\x0a\x01\x03"
);
}

XTAL_BIND2(Builtin){
	Xemb((

builtin::chain: fun(...args){
	return fiber{
		args.ordered_arguments{
			it{
				yield it;
			}
		}
	}
}

builtin::range: fun(first, last, step:1){
	if(step==1){
		return fiber{
			for(i:first; i<last; i++){
				yield i;
			}
		}
	}
	else{
		return fiber{
			for(i:first; i<last; i+=step){
				yield i;
			}
		}
	}
}

builtin::forever: fun fiber{
	i: 0;
	while(true){
		yield i;
		++i;
	}
}

	),
"\xdf\x78\x74\x61\x6c\x02\xe9\xf2\x01\x22\xff\x00\x30\x00\x02\x01\x4b\x00\x01\xff\x00\x8d\x00\x4b\x00\x02\x00\x86\xff\x02\x28\x00"
"\x00\xcd\x01\x01\x38\xff\x00\x05\x03\x02\x00\x36\x01\x02\xff\x00\x06\x02\x00\xcd\x00\xfb\x07\xff\xcd\x00\xfc\x07\xcd\x01\x00\x4d"
"\xff\x00\x01\xfb\x1d\x00\x03\x00\x51\x57\x00\x36\xfc\x19\x00\x01\x1d\x00\xfd\x21\x00\xed\xfe\x25\x03\x02\xfd\x2d\x01\x16\x00\x07"
"\xef\xcd\xfe\x00\x3d\x0c\x01\x00\x36\xfd\xf7\x02\x00\x07\x38\x09\xfd\x1d\xff\xf2\xff\x00\x05\x00\x1b\xff\xef\x00\x4f\xef\x00\x1f"
"\x00\x4e\x28\x00\x03\x00\x26\xfd\xff\x21\x00\x01\x07\xcd\xff\x00\x37\xdf\xfd\x01\x00\x08\x01\xf6\xf0\xcd\x10\x4f\x00\x1d\x00\x07"
"\x2e\x00\x85\x01\x25\x30\x00\x9d\x4e\x88\x00\x00\x00\x09\xea\xf1\x92\x00\x50\xe7\x00\x36\xfb\x5b\x04\x20\x05\xfb\x1d\xff\x55\xb7"
"\x6e\x02\xb4\x74\x06\x04\x7e\x09\xfb\x8b\x0f\xba\x9d\x06\xfb\xa7\x09\x3c\xcd\x00\x0c\x10\x01\xce\x0c\x12\x4a\x00\x0a\x54\x02\xfb"
"\xf3\x03\x00\x77\x5d\xff\x23\x2e\x00\x05\xff\x03\x0e\x00\xde\x31\x10\xff\x1e\x02\x01\xee\x00\x03\x00\xbd\x28\x04\x00\x04\x00\x21"
"\xff\x0b\x03\x28\x2e\xea\x00\x01\xff\x1f\x3a\x14\x14\x9a\x02\x53\x02\x6f\xff\x08\x00\xff\x4e\x19\xff\xf4\x6e\x02\xdd\xf1\x0c\x16"
"\x1b\x00\x29\x04\x00\x05\x00\x49\x25\x48\x1f\x2e\x00\x18\x5e\x17\x40\x10\x02\x36\x10\x59\x0d\x6a\x10\x4d\x1a\xff\xf0\x6e\x02\xed"
"\x0c\x1c\xdd\x11\x1c\x18\x06\x00\x21\x04\x00\x07\x00\x29\x1a\x30\x10\xe9\x01\x03\x3c\x12\x11\x5e\x1b\xfa\x13\xab\xff\xf7\x6e\x02"
"\xf4\x0c\x1c\x12\x1c\x14\x13\x12\x10\x12\x51\xa8\x03\xeb\xf0\x02\x6e\x00\xe6\xf5\x47\x25\xa8\xf2\xf1\x2d\x10\x00\x00\x00\x60\x22"
"\x05\x48\x24\x95\xaa\xeb\xf0\x0b\x2e\x00\x03\xeb\xf0\xa4\x00\x00\x11\xae\x62\x22\x00\x00\xc9\x80\x28\xf8\xeb\xf0\x12\x60\x84\x24"
"\x00\x10\x9a\x24\x85\x23\x45\x2b\x00\x08\xea\xf1\x20\x7b\x21\xf4\xf2\x65\x23\xea\xf1\x13\x01\x04\x60\x21\xcf\x22\x50\xbc\x24\x37"
"\x00\x6b\x22\xe3\x28\x98\x7b\x20\x0e\x78\x21\x14\xe8\x00\x7b\x20\x02\x7b\x21\xa7\x37\x00\x83\x22\x1c\x33\x1a\xe9\xf2\xcc\x17\x3f"
"\x00\xfb\x7b\x20\x9b\x22\x1f\x38\xa3\xfe\x06\x40\x3d\xb7\x28\xe9\xf2\x6d\xeb\xf0\x82\xaa\xeb\xf0\x89\xeb\xf0\x40\xeb\xf0\x55\xeb"
"\xf0\x5c\xa0\xe7\xf4\x84\x31\x84\x31\xea\xf1\x78\x31\x82\x1b\x32\x21\xf6\x00\x00\x01\x0b\xeb\xf0\x11\x74\x6f\x6f\xff\x6c\x2f\x74"
"\x65\x6d\x70\x2f\x69\x3b\x6e\x2e\xee\xf1\x00\x14\x0e\xea\xf1\xc3\x31\xff\x08\x74\x6f\x70\x6c\x65\x76\x65\xfd\x6c\xc3\x31\x07\x62"
"\x75\x69\x6c\x74\xfb\x69\x6e\xc3\x31\x04\x61\x72\x67\x73\xfa\xf2\xf1\x05\xc3\x31\x11\x6f\x72\x64\x65\xef\x72\x65\x64\x5f\xe6\x30"
"\x75\x6d\x65\xf7\x6e\x74\x73\xc3\x31\x0b\x62\x6c\x6f\xff\x63\x6b\x5f\x66\x69\x72\x73\x74\x3a\xc3\x31\x0a\x0a\x43\x6e\x65\x78\x14"
"\x42\x09\x44\xdf\x63\x61\x74\x63\x68\x05\x48\x62\x72\xf7\x65\x61\x6b\xc3\x31\x05\x63\x68\x61\xba\xdf\x33\x05\x10\x46\x04\x6c\x61"
"\x56\x44\x73\x57\x74\x65\x70\xf2\xf1\x0c\xf2\xf1\x0d\xf2\xf1\x7d\x0e\x44\x42\x72\x61\x6e\x67\x65\xd5\x32\xd7\x66\x6f\x72\xd1\x30"
"\x72\xc3\x31\x09\x66\xe7\x69\x6c\x65\x0b\x40\xbf\x30\x01\x03\x03"
);

}

namespace xpeg{

XTAL_BIND2(XpegOperator){
	Xemb((
		Element: xpeg::Element;
		elem: xpeg::elem;
		XpegOperator: xpeg::XpegOperator;

		more_Int: fun(left, n, kind){
			if(n==0){ return Element(Element::TYPE_MORE0, elem(left), null, kind); }
			else if(n==1){ return Element(Element::TYPE_MORE1, elem(left), null, kind); }
			else if(n==-1){ return Element(Element::TYPE_01, elem(left), null, kind); }

			if(n>0){ return xpeg::concat(left, more_Int(left, n-1, kind)); }
			else{ return xpeg::concat(more_Int(left, -1, kind), more_Int(left, n+1, kind)); }		
		}

		more_IntRange: fun(left, range, kind){
			if(range.begin()<=0){
				n: -(range.end()-1);
				return n < 0 ? more_Int(left, n, kind) : Element(Element::TYPE_EMPTY);
			}

			return xpeg::concat(left, more_IntRange(left, (range.begin()-1)..(range.end()-1), kind));
		}

		XpegOperator::op_div#Int: method(n){
			return more_Int(this, n, 1); 	
		}

		XpegOperator::op_div#IntRange: method(n){
			return more_IntRange(this, n, 1); 	
		}

		XpegOperator::op_mod#Int: method(n){
			return more_Int(this, n, 0); 	
		}

		XpegOperator::op_mod#IntRange: method(n){
			return more_IntRange(this, n, 0); 	
		}

		XpegOperator::op_mul#Int: method(n){
			return Element(Element::TYPE_GREED, more_Int(this, n, 0));
		}

		XpegOperator::op_mul#IntRange: method(n){
			return Element(Element::TYPE_GREED, more_IntRange(this, n, 0));
		}

		XpegOperator::op_or#XpegOperator: method(right){
			return xpeg::select(this, right);
		}

		XpegOperator::op_shr#XpegOperator: method(right){
			return xpeg::concat(this, right);
		}

		XpegOperator::op_com: method(){
			return ~xpeg::elem(this);
		}
	),
"\xdf\x78\x74\x61\x6c\x02\xe9\xf2\x02\x2b\xff\x01\x30\x00\x07\x00\x32\x00\x01\xbf\x00\x08\x00\x2f\x00\x00\xfa\xf3\x9b\x57\x01\x00"
"\x09\x04\x00\x01\xfa\xf6\x0a\x04\x00\xf7\x02\x00\x4b\x00\x00\xad\x01\x03\xcd\xff\x00\xfe\x1e\x02\x01\x00\x1d\x00\xff\x03\x00\x1c"
"\x01\x2e\x00\x00\x03\xfe\x39\x00\x02\x32\xcd\x03\x00\x12\x04\xff\x2e\x00\x01\x05\x07\xcd\xfd\x03\xff\x34\x04\x01\x01\x05\x04\x01"
"\xcd\xfd\x00\x4a\x00\xff\x00\x34\x01\x01\x04\xff\x02\x00\x3c\xcd\x01\x00\x1b\x00\x25\x42\x2a\x00\x01\x2e\x0f\x40\x02\x13\x46\x0f"
"\x58\x0e\x5d\x22\x6a\x01\x01\x0b\x02\x6d\x07\x1a\x38\x0a\xf1\x14\x86\x0f\x58\x0b\x2a\x01\x01\x1f\x02\xfe\xf6\x72\x02\x1f\x02\xfb"
"\xf0\x01\x32\xcd\x02\xa7\x00\x15\x02\xcf\x00\xca\x00\x03\xce\x01\x07\xfe\x6b\x00\x06\x0e\x07\xfe\x00\x08\x07\xac\x59\x00\xd2\x01"
"\x03\x05\x5c\x01\x02\x61\x05\x27\xac\xf8\x07\x3c\x00\x03\x04\xcf\x00\x05\x6b\x00\x05\xef\x0b\x06\x05\x06\x59\x00\x02\x34\x03\x97"
"\x01\x03\x04\x06\x1a\x0d\x14\x1f\x26\x14\x3c\xeb\xcd\x00\x04\x00\x03\x24\x00\x02\x00\x6a\x7f\x01\x38\x00\x1d\x02\xfd\x02\x2b\x00"
"\xd7\x02\x1f\x03\x71\x01\x36\x34\x00\x38\x00\x77\x1e\x01\xfd\x6a\x01\xff\x0e\x01\xf6\xf0\xef\xff\x0b\x00\xff\x8e\x11\xff\x1f\x03"
"\xbb\x02\x01\x73\x01\x07\x00\x01\x42\x00\x1b\xab\x00\x04\xbe\x10\x02\x72\x02\x10\x38\x00\x03\xa6\x02\x10\xfc\x03\x59\x00\x3e\x10"
"\xfe\x5c\x01\x03\x55\x02\x66\x00\x0c\x38\x0a\x1f\x5c\x01\x01\x61\x02\x6a\xf8\x0a\xfc\xca\x00\x04\xce\x00\xfc\x08\x89\x10\xf7\x09"
"\xfd\x09\x6b\x00\x07\x0e\x09\x08\x77\x00\x0a\x09\x9d\x10\x0a\xfd\x0a\x6b\x00\xff\x08\x0e\x0a\x09\x00\x0b\x06\x3f\x97\x07\x00\x09"
"\x65\x11\xfe\x6a\x1f\x7c\x12\x04\xbf\x00\x2e\x00\x02\x01\x4b\x34\x00\x11\x82\xd0\x12\x06\xd8\x12\x6b\x00\xe0\x14\x77\x14\xf8\x00"
"\x23\x3f\x00\x4a\x00\x22\x08\x02\x64\x00\x5b\x23\xa5\x04\x62\x22\x04\x68\x2f\x7a\x26\x26\x84\x2c\x05\x52\x62\x2c\x00\x72\x2f\x84"
"\x20\x29\x88\x28\x06\x94\x2c\xb8\xd5\x2f\xb5\x21\xeb\x29\x07\x00\x1b\x38\x0a\x2e\x92\x06\x12\x06\x4a\x11\x0e\x10\x00\x42\x2f\x7e"
"\x26\x2f\x02\x88\x28\x08\x2a\x3f\x12\x20\x3f\x3f\x51\x3b\xb5\x21\x63\x39\x17\x09\x00\x12\xf8\x06\x34\x9a\x23\x4e\x3c\x5b\x20\x2a"
"\x84\x20\x35\x88\x28\x0a\xb6\x38\x15\xc2\x3f\xd4\x36\x75\x38\x88\x28\x0b\xb6\x38\x09\x02\x06\xf8\x14\xf9\x0c\xa8\x10\x77\x15\x4a"
"\x00\x39\x00\x00\xee\x64\x00\x30\x00\x3a\x62\x02\x51\x00\x0d\xc2\xe7\xf4\x02\xc4\x10\xe6\xf5\x27\x40\xc4\x20\x00\x00\x55\x15\xeb"
"\xf0\x0c\x34\x00\x03\xeb\xf0\xc4\xeb\xf0\x59\x17\xc4\x10\x75\x40\x01\x32\xeb\xf0\x20\x00\x00\x5c\xa8\x10\x5e\x20\x00\x00\x24\x8a"
"\x44\x64\xeb\xf0\x55\x27\x8a\x44\x7d\xeb\xf0\x2a\x8a\x44\x96\xeb\xf0\x55\x2c\x8a\x44\xb9\xeb\xf0\x30\x8a\x44\xdc\xeb\xf0\xd4\xff"
"\xf1\x8d\x41\xf6\xeb\xf0\x36\x8a\x43\x02\x10\x40\xeb\xf0\x41\x40\xeb\xf0\xa8\x10\x60\x4a\xe9\xf2\x0c\xea\xf1\x50\x75\x41\xeb\x44"
"\xc5\x10\xe9\xf2\x18\x75\x40\x0f\x72\x41\x5e\xa8\x10\x03\x00\x0b\x03\x75\x41\xc7\x75\x40\x69\x1a\x7e\x41\x11\x52\x16\x2b\x51\x01"
"\x35\x69\x40\xa1\x21\x8a\x41\x8d\x41\x06\x00\x8d\x41\x4e\x69\x40\x25\xaa\x49\x5c\x67\x69\x40\x28\x49\x5c\x80\x69\x40\x2b\xaa\x49"
"\x5c\x99\x69\x40\x2d\x49\x5c\xbc\x69\x40\x31\xaa\x49\x5c\xdf\x69\x40\x33\x49\x5c\xf9\x69\x40\x37\x06\x49\x5b\x02\x13\x69\x40\xe9"
"\x42\xef\x45\xec\x57\xea\x45\xf5\x02\xad\x42\x0b\xeb\xf0\x11\x74\x6f\x6f\xff\x6c\x2f\x74\x65\x6d\x70\x2f\x69\x3b\x6e\x2e\xee\xf1"
"\x00\x3b\x0e\xea\xf1\x25\x61\xff\x08\x74\x6f\x70\x6c\x65\x76\x65\xfd\x6c\x25\x61\x07\x45\x6c\x65\x6d\x65\x9b\x6e\x74\x25\x61\x04"
"\x65\x3d\x60\x25\x61\x0c\xff\x58\x70\x65\x67\x4f\x70\x65\x72\xef\x61\x74\x6f\x72\x2a\x62\x6d\x6f\x72\xd7\x65\x5f\x49\x41\x63\x0d"
"\x62\x65\x52\x61\x17\x6e\x67\x65\x43\x62\x78\x52\x60\xf2\xf1\x60\x00\x57\x00\x00\x05\xf2\xf1\x06\xf2\xf1\x07\x43\x62\xb7\x6c\x65"
"\x66\x42\x62\x01\x6e\x43\x62\x6b\x57\x69\x6e\x64\xf2\xf1\x0a\xf2\xf1\x0b\xf2\xf1\xfd\x0c\x25\x61\x0a\x54\x59\x50\x45\x5f\x5f\x4d"
"\x4f\x52\x45\x30\xc0\x6b\x31\x37\x62\xfa\xc5\x62\x30\xdd\x62\x06\x63\x6f\x6e\x63\xcb\x61\x74\xf2\xf1\x08\xb1\x62\x25\x61\x05\x72"
"\xe8\x78\x61\xbb\x62\xb1\x66\x11\xbb\x66\x05\x62\x65\x7b\x67\x69\xa7\x62\x03\x65\x6e\x64\xc0\x67\x5f\x45\x4d\x50\x54\x59\xb6\x66"
"\x0b\xea\x62\x3f\x6f\x70\x5f\x64\x69\x76\x27\x72\x67\x60\x32\x3e\x7b\x08\x74\x65\x3e\x7f\x6d\x6f\xb0\x62\x42\x73\x7c\x72\x7b\xc4"
"\x63\x47\x52\x45\x45\x44\x7c\x76\xf9\x75\xf1\xf2\x42\x77\x05\x72\x69\x67\x68\xaa\xf4\x62\x1b\xea\x62\x73\x48\x60\x63\x42\x62\x05"
"\xc6\x4d\x70\x6f\x72\xc9\x72\xc9\x77\x4d\x70\x73\x68\xec\x5c\x62\x4c\x71\x63\x6f\x4b\x62\x09\x66\x69\xdf\x6c\x65\x6c\x6f\x63\x21"
"\x60\x01\x03\x01\x03"
);
}

XTAL_BIND2(Element){
	Xemb((
		xpeg::Element::set_body: method(term){ 
			if(this.type==xpeg::Element::TYPE_DECL){
				this.param1 = xpeg::elem(term);
			}
		}
	),
"\xdf\x78\x74\x61\x6c\x02\xe8\xf3\x32\x01\xff\x30\x00\x02\x00\x32\x00\x01\x00\xf7\x03\x01\x4b\x00\x00\x24\x02\x06\x01\xbf\x38\x00"
"\x06\x03\x02\x04\xfb\xf0\x03\xff\x32\x00\x04\x00\x03\x02\x32\x1c\xff\x03\x00\x07\x01\x1e\x03\x02\x00\x9f\x1d\x00\x03\x00\x11\x0e"
"\x00\xfb\xf0\x02\xff\x32\xcd\x03\x00\x09\x03\x07\xcd\xff\xff\x01\x34\x02\x01\x01\x03\x00\xff\x39\x00\x08\x01\x00\x00\x3c\xcd\xff"
"\x00\x00\x4a\x00\x0a\x00\x00\xcd\xdf\x01\x00\x30\x00\x0b\x48\x00\x01\x00\x89\x51\x28\x00\xe8\xf3\x02\x00\x00\xe6\xf5\x67\x05\x05"
"\x02\xeb\xf0\x04\x00\x00\x81\x01\x61\x0f\xfc\xf0\xeb\xf0\x5f\x05\x14\x46\x00\x83\x05\x08\x7b\x00\x05\x80\x01\xa7\x02\xb9\x01\xac"
"\x8f\x08\xa4\x03\x00\x31\x80\x01\x0b\xeb\xf0\x11\xff\x74\x6f\x6f\x6c\x2f\x74\x65\x6d\xdf\x70\x2f\x69\x6e\x2e\xee\xf1\x00\x0c\xf9"
"\x0e\xea\xf1\xf3\x01\x08\x74\x6f\x70\x6c\xef\x65\x76\x65\x6c\xf3\x01\x04\x78\x70\xfb\x65\x67\xf3\x01\x07\x45\x6c\x65\x6d\xf7\x65"
"\x6e\x74\x05\x12\x74\x65\x72\x6d\xba\xf2\xf1\x06\x1a\x13\x79\x70\x65\xf3\x01\x09\xff\x54\x59\x50\x45\x5f\x44\x45\x43\xfd\x4c\xf3"
"\x01\x0a\x73\x65\x74\x5f\x70\x5f\x61\x72\x61\x6d\x31\x05\x12\x65\x14\x10\xbc\xf8\x02\x44\x11\x62\x6f\x64\x79\x31\x12\x66\xbf\x69"
"\x6c\x65\x6c\x6f\x63\xef\x00\x01\x03\x03\x03"
);
}

XTAL_BIND2(Xpeg){
	Xemb((
		elem: xpeg::elem;
		Element: xpeg::Element;

		xpeg::set: fun(str){
			chset: Set();
			str.each{
				chset[it] = true;
			}
			return Element(Element::TYPE_CH_SET, chset);
		}

		xpeg::call: fun(f){
			return Element(Element::TYPE_CALL, f);
		}

		xpeg::select: fun(left, right){
			eleft: elem(left);
			eright: elem(right);

			if((eleft.type==Element::TYPE_EQL || eleft.type==Element::TYPE_CH_SET) && 
				(eright.type==Element::TYPE_EQL || eright.type==Element::TYPE_CH_SET)){

				chset: Set();

				if(eleft.type==Element::TYPE_EQL){
					chset[eleft.param1] = true;
				}

				if(eleft.type==Element::TYPE_CH_SET){
					eleft.param1{
						chset[it] = true;
					}
				}

				if(eright.type==Element::TYPE_EQL){
					chset[eright.param1] = true;
				}

				if(eright.type==Element::TYPE_CH_SET){
					eright.param1{
						chset[it] = true;
					}
				}
				return Element(Element::TYPE_CH_SET, chset);
			}

			return Element(Element::TYPE_OR, eleft, eright); 
		}

		xpeg::concat: fun(left, right){ 
			eleft: elem(left);
			eright: elem(right);

			if(eleft.type==Element::TYPE_CONCAT){
				return Element(Element::TYPE_CONCAT, eleft.param1, Element(Element::TYPE_CONCAT, eleft.param2, eright));
			}

			return Element(Element::TYPE_CONCAT, eleft, eright); 
		}

		xpeg::lookahead: fun(left){
			return Element(Element::TYPE_LOOKAHEAD, elem(left));
		}

		xpeg::lookbehind: fun(left, back){
			return Element(Element::TYPE_LOOKBEHIND, elem(left), back);
		}

		xpeg::cap: fun(...arg){
			named: arg.named_arguments[];

			if(!named.empty){ 
				return Element(Element::TYPE_CAP, elem(named[0][1]), named[0][0]);
			}
			
			ordered: arg.ordered_arguments[];
			if(ordered.length==2){ 
				return Element(Element::TYPE_CAP, elem(ordered[1]), ordered[0]);
			}

			return null;
		}

		xpeg::node: fun(...arg){
			named: arg.named_arguments[];

			if(!named.empty){ 
				return Element(Element::TYPE_NODE, elem(named[0][1]), named[0][0]);
			}
			
			ordered: arg.ordered_arguments[];
			if(ordered.length==1){ 
				return Element(Element::TYPE_CAP, elem(ordered[0]));
			}

			if(ordered.length==2){ 
				return Element(Element::TYPE_CAP, elem(ordered[1]), ordered[0]);
			}

			return null;
		}

		xpeg::splice_node: fun(num, ...arg){
			named: arg.named_arguments[];
			if(!named.empty){
				return Element(Element::TYPE_NODE, elem(named[0][1]), named[0][0], num);
			}

			ordered: arg.ordered_arguments[];

			if(ordered.length==1){
				return Element(Element::TYPE_NODE, elem(ordered[0]), null, num);
			}

			if(ordered.length==2){ 
				return Element(Element::TYPE_NODE, elem(ordered[1]), ordered[0], num);
			}
		
			return null;
		}

		xpeg::leaf: fun(left){
			return Element(Element::TYPE_LEAF, elem(left));
		}

		xpeg::leafs: fun(left){
			return Element(Element::TYPE_LEAF, elem(left), null, 1);
		}

		xpeg::back_ref: fun(n){
			return Element(Element::TYPE_BACKREF, n);
		}

		xpeg::decl: fun(){
			return Element(Element::TYPE_DECL);
		}

		xpeg::bound: fun(body, sep){
			return lookbehind(sep, 1) >> body >> lookahead(sep);
		}

		xpeg::error: fun(fn){
			return Element(Element::TYPE_ERROR, fn);
		}

		xpeg::pred: fun(e){
			return Element(Element::TYPE_PRED, e);
		}
				
		xpeg::any: Element(Element::TYPE_ANY);
		xpeg::bos: Element(Element::TYPE_BOS);
		xpeg::eos: Element(Element::TYPE_EOS);
		xpeg::bol: Element(Element::TYPE_BOL);
		xpeg::eol: Element(Element::TYPE_EOL);
		xpeg::empty: Element(Element::TYPE_EMPTY);

		xpeg::degit: elem("0".."9");
		xpeg::lalpha: elem("a".."z");
		xpeg::ualpha: elem("A".."Z");
		xpeg::alpha: xpeg::lalpha | xpeg::ualpha;
		xpeg::word: xpeg::alpha | xpeg::degit | "_";

		//ElementPtr ascii = elem(xnew<ChRange>(intern(Xs("\x01")), intern(Xs("\xfe"))));

),
"\xdf\x78\x74\x61\x6c\x02\xe9\xf2\x05\x8c\xff\x01\x30\x00\x04\x00\x32\xcd\x01\xbf\x00\x05\x00\x2f\x00\x00\xfa\xf3\xc9\xb7\x01\x00"
"\x06\x04\x00\x01\x00\xfb\xf0\x01\x75\x4b\x14\x00\x5b\x16\x00\x09\xfc\x34\x14\x00\xff\x01\x01\x38\x00\x0a\x02\xfb\x00\xff\x36\x01"
"\x02\x00\x0b\x02\x00\xcd\x7f\x00\xfd\x07\xcd\x00\xfe\x07\x00\x00\xff\x4d\x00\x01\xfd\x1d\x00\x03\x00\xff\x16\x00\x01\xcd\x03\xfc"
"\x1a\x00\xfd\xfe\x00\x00\x36\xfd\x02\x00\x0c\x01\xde\x37\x08\xfd\x1d\xff\xf2\x02\x00\x1b\xff\x7f\xef\x00\x4f\x00\x1f\x00\x4e\x42"
"\x00\xef\x02\x00\x26\xff\x3b\x00\x01\x07\xcd\xff\xff\x00\x37\xfd\x01\x00\x0d\x01\x7e\x06\x00\xcd\x10\x00\x1d\x00\x07\x48\x00\xee"
"\x83\x01\x25\x00\x51\x76\x00\x37\xfd\x00\xf3\x00\x0e\xea\xf1\x90\x00\x50\x01\x2e\x00\xfb\x01\x03\xb1\x00\x02\x32\xcd\x03\x00\xff"
"\x0f\x03\x07\xcd\xfc\x00\x34\x01\xdf\x01\x02\x02\x00\x3c\x00\x00\x3c\xcd\x9f\x00\x00\x4a\x00\x10\xaa\x00\x15\x05\x02\xab\x00\x13"
"\xb0\x0a\x13\xbe\x00\xff\xc2\x0e\x14\xbe\xd4\x08\x03\x01\x58\x00\x2e\x06\x00\x07\xb7\xcd\xf8\xfa\x25\x00\x01\x01\x14\x14\xf9\xfd"
"\xfb\x1d\x12\x02\x38\x00\x19\x03\xfa\xfd\x04\xb1\x01\x32\xcd\x04\x00\x1a\x02\xaf\x1e\x04\x03\x01\x47\x01\x07\x4c\x01\x00\xdd\x1b"
"\xfc\xf0\x01\xcd\x02\x92\x00\x16\x00\xe5\x03\x30\x1c\x0f\x40\x1f\x52\x14\x03\x00\x2c\x02\x30\x12\xfb\x36\x1f\x48\x1f\x5a\x14\x8d"
"\x17\x6b\x1f\x7d\x17\xdd\xe0\x20\x0a\x19\x02\xfa\xb4\x06\x1a\x01\xfb\x1e\x03\x81\x13\x0b\x00\x38\x00\x1b\xa7\x01\xfa\x01\x4d\x02"
"\x5c\x00\x02\xea\x1c\x0f\x3a\xfa\x16\x46\x2a\x00\x1b\x02\xfa\x30\x0f\x42\x00\x11\x03\x46\x0f\x58\x0f\x6a\x0e\x04\x7c\x0f\x8e\x0f"
"\xa0\x0e\x12\xeb\x11\xfb\xf0\x1f\x02\x24\xfb\x0a\x2c\xb9\x27\x23\x2d\x44\x2f\x0f\x41\x01\x05\x4a\x2f\x5c\x2f\x6a\x0e\x06\x80\x2f"
"\xa0\x92\x2f\xa0\x0f\xb2\x0f\xc4\x05\x7e\x3a\x1c\xbe\x00\xfa\x8f\x04\x07\xcd\xfb\xc2\x01\xfc\x10\xc9\x07\x1d\xb2\xd4\x08\x04\x76"
"\x00\x15\x13\xfc\xfe\x1d\x19\xfd\xa9\xff\x1d\x12\xea\x12\xfe\x82\x36\x22\xfa\x16\x21\x76\x7e\x3a\x22\x03\x05\x20\x04\xfe\x05\x7f"
"\x30\xfd\x07\x7f\x30\x06\x32\xcd\x07\x00\x22\x7f\x07\x38\x00\x23\x08\xfe\x08\x51\x30\x3f\x04\x34\x05\x01\x03\x06\xb0\x37\x06\x4c"
"\x47\x07\xcd\xfe\xac\x30\xf3\x02\xb4\x3a\x24\xd4\x08\xd7\x05\x00\x18\x7e\x3a\x27\x8e\x10\x00\x05\x7e\x51\x30\x03\x34\x04\x01\x01"
"\x05\xc2\x0e\xa5\x28\xd4\x08\x06\xf8\x10\x7f\x39\x2d\x86\x44\xfe\xe0\x8e\x43\x54\x4f\xd0\x00\x15\x10\xd6\x06\x07\x00\x65\xfe\x04"
"\x20\x31\x01\xfd\xfe\x38\x00\x32\xbe\x5a\x30\x38\x00\x33\x01\xfe\x60\x30\x28\xf4\x10\x10\x7f\x39\x34\x86\x41\x07\x03\xcd\x00\xbf"
"\x06\x19\x07\xfe\xcd\x08\x1e\x50\x01\xbf\x05\x19\x07\x06\xcd\x08\x8e\x43\x06\x7e\x1f\x50\x05\x19\x06\xfe\xcd\x07\x38\x51\xcf\x04"
"\x19\x06\x05\x24\x40\xb1\x37\x38\x00\xcf\x35\x01\xfd\xff\xfb\x42\x2a\x00\x36\x02\x27\xff\x02\x03\x12\x20\xfb\x15\x1e\x0c\x5f\x38"
"\x50\x5e\x2b\x50\x06\xff\xcd\x07\x8e\x43\x05\x43\x52\xa7\x05\xff\xcd\x37\x48\x1a\x30\x00\xc8\x08\x37\xce\xd4\x08\x08\x00\x85\xf4"
"\x4f\x06\x5f\x00\x3a\xa0\x1a\x5f\x2c\x5f\x3e\x5f\x50\x5f\x62\x56\x01\xfa\x16\x19\x00\x76\x5f\x0e\x64\x8f\x56\x90\x38\x63\x5f\x75"
"\x5f\x87\x5f\x99\x5f\x3a\xab\x5d\x3b\xd4\x08\x09\x00\x8d\xca\x5f\x60\x30\x81\x2a\xe0\x5f\xf2\x5f\x04\x6f\x16\x69\x8a\x40\xc1\x02"
"\x04\x24\x27\x6f\x39\x6f\x1d\xf8\x6f\x5e\x6d\x04\xad\x50\x38\x7b\x06\x78\x6f\x00\x20\x66\x7f\x9e\x6f\xb0\x65\x38\x7c\xad\x5b\x95"
"\x40\xd4\x08\x0a\x76\x4c\x43\x86\x4f\xc6\x0a\x44\x0e\xd4\x08\x0b\x00\x1c\x06\x8f\x18\x87\x88\x72\x15\x70\x54\x3c\x78\xcd\x03\x47"
"\xd4\x08\x0c\xe0\x0c\x4a\xf0\x0f\xba\xd0\x00\x4b\xd4\x08\x0d\x00\x11\x7e\x3a\x4c\xe8\xc2\x01\x00\x30\xc9\x07\x4d\xd4\x08\x0e\x00"
"\x1d\xcf\x03\x30\x00\x2e\xd0\x41\x62\x81\x02\x34\xff\x03\x01\x02\x04\x01\x17\xfe\x02\xcb\x00\x03\xe6\x80\x28\xd0\x41\xf2\x81\x01"
"\x04\x4f\x00\x17\x02\x01\x16\x30\xc9\x07\x52\xd4\x08\xa5\x0f\xe0\x0c\x55\x94\x8f\xd0\x00\x56\xd4\x08\x10\x52\xe0\x0c\x59\x3a\x9f"
"\xd0\x00\x5a\xd4\x05\x02\x7f\x30\x9e\x8e\x16\x5b\x01\x34\x02\xb2\x30\xd0\x00\x5c\x94\x82\x9f\x94\x10\x5d\x98\x96\x5e\xa2\x9f\x94"
"\x10\x5f\x52\x98\x96\x60\xc2\x9f\x94\x10\x61\x98\x96\x62\xe2\x9f\x4a\x94\x10\x63\x98\x96\x64\x02\xaf\x94\x10\x65\x98\x96\xf9\x33"
"\x22\xa8\x88\x90\x00\x01\x05\x02\x00\x7f\x02\x03\x3f\x04\x00\x06\x05\x98\x96\x55\x66\x42\xac\x03\x52\xa0\x04\x56\xac\x67\x42\xac"
"\x95\x05\x52\xa0\x06\x56\xac\x68\xd4\x05\xe6\x80\x04\xe6\x86\x32\x67\x04\xb3\xa1\x93\x11\x68\x01\x14\xca\xfc\x10\x04\xd0\x00\x69"
"\xd4\x05\xc0\xa6\x69\x05\xfe\xd9\xa1\x32\xcd\x05\x00\x66\x02\x14\xbb\x04\x03\x61\x80\x02\x00\x07\xca\xa6\x6a\xba\xd4\x04\x6b\xc8"
"\x02\x51\x00\x12\xe7\xf4\x02\x84\xc6\x50\xe6\xf5\x02\x02\x80\xf2\xf1\xd3\x00\x62\x30\x05\x2e\x14\x00\x00\x00\x71\xeb\xf0\x11\x26"
"\x01\xeb\xf0\x65\x8a\xeb\xf0\x15\xc6\x50\xf2\xf0\x01\xe8\xeb\xf0\x59\x1e\xfc\xf0\xf2\xf0\x02\x3c\xeb\xf0\x25\x40\xb3\x4d\x02\x81"
"\x90\x00\x29\x7a\x00\x5b\xb1\x7a\xeb\xf0\xa9\x2f\x16\x30\x67\xb1\xe5\xeb\xf0\x38\x7c\xb3\x03\xe5\x70\xeb\xf0\x3c\x58\xb3\xf2\xa0"
"\x00\x00\x41\x56\x40\xb3\x04\x21\xeb\xf0\x45\xa0\xb4\x43\xeb\xf0\x61\x48\xa0\xb4\xa1\x90\xc4\x80\xe9\xf2\x04\x73\xeb\xf0\xad\x4e"
"\x70\xb3\x04\x96\xeb\xf0\x53\xa0\xb4\xaf\x42\xeb\xf0\x57\x40\xb2\x37\xb1\x23\xb9\xe9\xf2\x11\xea\xf1\xa8\x9b\xb1\xea\xf1\x5a\x30"
"\x08\xec\xb4\x13\x9b\xb0\x08\xa4\x34\xb1\x5a\x30\x05\x06\x00\x37\xb1\x74\x9b\xb0\x12\x28\x26\x02\x0d\xc2\x29\xc2\x8d\x9b\xb0\x17"
"\x4c\xb1\x0f\xc2\x5d\x00\xc6\x00\x00\x01\xeb\x9b\xb0\x20\x58\xb1\xac\xa3\xb1\x4f\xc3\x02\x3f\x9b\xb0\x26\x33\xcb\x02\x45\x5d\x9b"
"\xb0\x2b\x70\xb1\x67\xb1\x63\xc4\x7d\xfc\x10\x51\x30\x7c\xb1\x8b\xb1\x15\xb4\xe8\xfc\x10\x39\x97\xcb\xcb\x03\x73\xfc\x10\x3e\x5b"
"\xc7\x22\xc1\x04\x06\x5a\x9b\xb0\x42\x33\xcb\x04\x24\x9b\xb0\x46\xd3\xcc\x15\x46\x9b\xb0\x49\xd3\xcc\x5f\x9b\xb0\xc3\xb2\xed\xb5"
"\x6a\x4c\xa0\x76\x9b\xb0\x50\x83\xcb\x04\x99\x9b\xb0\x55\x54\xd3\xcc\xb2\x9b\xb0\x58\x33\xca\x07\xdf\xfc\x15\x3f\xeb\xf0\x54\xeb"
"\xf0\x5b\xe7\xf4\x6c\xd1\x6c\xd0\x33\x01\x41\x06\x00\x4f\x90\x01\x5d\x09\xc4\x84\xd1\x2a\x84\xd1\xa6\x06\x00\xbb\x06\x00\xc2\x09"
"\xc4\x9c\xd1\xad\xbb\x36\xb1\x05\x8b\x26\x01\x0b\x3c\xb1\x74\xff\x6f\x6f\x6c\x2f\x74\x65\x6d\x70\x6f\x2f\x69\x6e\x2e\xee\xf1\x00"
"\x6c\x75\x32\xfe\x75\x31\x08\x74\x6f\x70\x6c\x65\x76\x7d\x65\xce\xd2\x04\x65\x6c\x65\x6d\x75\x31\xbb\x07\x45\xe7\xd0\x65\x6e\x74"
"\xe1\xd2\x78\x87\x70\x65\x67\xf2\xf1\x40\x70\xf6\xf0\x75\x31\x03\xd7\x73\x74\x72\xf2\xf1\x07\x09\xe2\x53\x65\xde\xf5\xd3\x65\x61"
"\x63\x68\x75\x31\x0b\x62\xff\x6c\x6f\x63\x6b\x5f\x66\x69\x72\x75\x73\xf5\xd2\x0a\x2c\xe3\x6e\x65\x78\xf5\xd2\xee\x2b\xe4\x63\x61"
"\x74\x25\xea\x62\x72\x65\xfb\x61\x6b\x27\xe2\x54\x59\x50\x45\x5f\x3f\x43\x48\x5f\x53\x45\x54\x09\xe3\x1c\xe3\xd3\x01\x66\x2b\xb2"
"\x75\x31\x09\x6b\xe3\x41\x4c\xdd\x4c\xe1\xd2\x63\x61\x6c\xe0\xd3\x6c\x65\xfd\x66\xf5\xd2\x05\x72\x69\x67\x68\x74\xea\xf2\xf1\x13"
"\xf2\xf1\x14\xe1\xd2\x74\x79\x70\xd9\x65\xd4\xd2\x6b\xe2\x45\x51\x96\xe2\x06\x70\x9f\x61\x72\x61\x6d\x31\xea\xd2\x6b\xe2\x4f\x15"
"\x52\xd3\xe2\x73\xe6\xd0\x63\xb2\xe8\xb3\xeb\x6a\xe4\x4f\x4f\x4e\x43\x41\x75\xe2\xd7\xe3\x32\xd3\xe2\xa7\x63\x6f\x6e\x51\xe0\xb3"
"\xe6\x13\x75\x31\x0e\xfe\x6b\xe2\x4c\x4f\x4f\x4b\x41\x48\x45\xfb\x41\x44\x89\xe2\x6c\x6f\x6f\x6b\x61\xef\x68\x65\x61\x64\x34\xf6"
"\x04\x62\x61\xab\x63\x6b\xb3\xe6\x1f\x75\x31\x0f\x3e\xf6\x42\xaf\x45\x48\x49\x4e\x4b\xf2\x0a\x51\xf1\x62\xdf\x65\x68\x69\x6e\x64"
"\x09\xe2\x61\x72\xfa\xfe\xd2\x22\x72\xf2\x6e\x61\x6d\x65\x64\xd5\x5f\x9a\xf0\x75\xf2\xd1\x73\x27\xe2\x6f\x70\x77\x5f\x74\x6f\xac"
"\xf0\x72\x61\x79\xa9\xe2\x72\xc2\xd0\x74\xc5\xf2\xca\xe3\x43\x41\x50\x75\x31\xbf\x11\x6f\x72\x64\x65\x72\xaa\xfd\x06\xdf\x6c\x65"
"\x6e\x67\x74\x26\xe2\x03\x63\xe3\x61\x70\x9d\xf2\x9d\xf6\x8d\xe3\x4e\x4f\x44\xdd\x45\xe1\xd2\x6e\x6f\x64\xc5\xe2\x03\x6e\xeb\x75"
"\x6d\x06\x06\x2c\x9d\xf6\x0b\x73\x70\x1f\x6c\x69\x63\x65\x5f\x23\x01\x2f\xfb\x8d\xe3\x2f\x4c\x45\x41\x46\xa0\xe4\x61\x83\xe2\x33"
"\xf7\x99\x05\x6b\x01\xb5\xf2\x01\x6e\xf9\xb1\xdd\xe2\x0c\x7e\x6b\xe2\x42\x41\x43\x4b\x52\x45\x65\x02\xbd\x08\x64\xf1\x5f\x72\x65"
"\x66\x89\xe7\x44\xbb\x45\x43\x96\xe3\x64\x65\x63\xe0\xd3\x62\xa3\x6f\x64\xc5\xf2\x7a\xe0\x05\x02\x36\xf9\xb1\x37\x6e\xa9\xe2\x62"
"\x6f\x75\x93\xf3\x02\x66\x88\x02\xd9\x39\x37\xe2\xcb\xe3\x52\x52\xe8\xe3\x05\x65\x4f\x72\x72\x6f\x72\x7e\xe2\x4d\x02\x3c\x89\xe7"
"\x37\x50\x52\x45\x4b\xf2\x04\x70\xe6\xf0\xc6\xe7\xd7\x41\x4e\x59\x95\xf3\x6e\xcf\xf8\x42\x4f\x8d\x53\x09\xe2\x62\x6f\xb5\xf2\xca"
"\xe4\x4f\x14\x65\x06\x57\x19\x42\x4f\x96\xe2\x55\x10\xce\xd2\x5d\x15\x7a\x13\xb9\x65\x81\x13\xf8\x04\x4d\x50\x54\x3b\x12\x05\xef"
"\x64\x65\x67\x69\xf5\xd2\x06\x6c\x61\xaf\x6c\x70\x68\x61\xd3\xe2\x75\xb7\x16\x05\xe6\xb7\x16\x04\x77\xe2\xf0\x89\xe2\x66\x69\x6c"
"\x59\x65\x2d\xe0\xcb\xd0\x08\x03\x7e\xe2\x30\x7e\xe2\x5a\xf3\x02\x01\xbb\x12\x01\x7a\x7e\xe2\x41\x7e\xe2\x0d\x5a\x7e\xe2\x5f\x03"
""
);

}

}

//*/

}
